<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3155: tuple&lt;any, any&gt;{allocator_arg_t, an_allocator}</title>
<meta property="og:title" content="Issue 3155: tuple&lt;any, any&gt;{allocator_arg_t, an_allocator}">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3155.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Resolved">Resolved</a> status.</em></p>
<h3 id="3155"><a href="lwg-defects.html#3155">3155</a>. <code>tuple&lt;any, any&gt;{allocator_arg_t, an_allocator}</code></h3>
<p><b>Section:</b> 22.4.4.2 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2018-08-18 <b>Last modified:</b> 2021-10-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#tuple.cnstr">active issues</a> in [tuple.cnstr].</p>
<p><b>View all other</b> <a href="lwg-index.html#tuple.cnstr">issues</a> in [tuple.cnstr].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
For a 2-element <code>std::tuple</code>, attempting to call the "allocator-extended default constructor" might actually
pass the <code>allocator_arg</code> tag and the allocator to the tuple element constructors:
</p>
<blockquote>
<pre>
tuple&lt;any, any&gt; t{allocator_arg, allocator&lt;int&gt;{}};
assert(std::get&lt;0&gt;(t).has_value());
</pre>
</blockquote>
<p>
This assertion should pass according to the standard, but users might expect the elements to be default constructed.
If you really wanted to construct the elements with the tag and the allocator, you could do:
</p>
<blockquote>
<pre>
tuple&lt;any, any&gt; t{{allocator_arg}, {allocator&lt;int&gt;{}}};
</pre>
</blockquote>
<p>
or
</p>
<blockquote>
<pre>
tuple&lt;any, any&gt; t{tuple&lt;allocator_arg_t, allocator&lt;int&gt;&gt;{allocator_arg, allocator&lt;int&gt;{}}};
</pre>
</blockquote>
<p>
The deduction guides for <code>std::tuple</code> always treat <code>{allocator_arg_t, <i>an_allocator</i>}</code> as the
allocator-extended default constructor, so this creates an empty tuple:
</p>
<blockquote>
<pre>
tuple t{allocator_arg, allocator&lt;int&gt;{}};
</pre>
</blockquote>
<p>
And this is needed to create <code>tuple&lt;any, any&gt;</code>:
</p>
<blockquote>
<pre>
tuple t{allocator_arg, allocator&lt;int&gt;{}, any{}, any{}};
</pre>
</blockquote>
<p>
The proposed resolution seems consistent with that, always calling an allocator-extended constructor for
<code>{allocator_arg_t, <i>a</i>}</code>, instead of the <code>tuple(UTypes&amp;&amp;...)</code> constructor.
<p/>
Ville Voutilainen:
<p/>
This was discussed in <a href="http://lists.isocpp.org/lib-ext/2016/10/3154.php">this reflector thread</a>,
where Andrzej convinced me to change libstdc++ tuple.
</p>

<p><i>[2018-08-20, Daniel comments]</i></p>

<p>
The wording changes by this issue are very near to those suggested for LWG <a href="lwg-defects.html#3121" title="tuple constructor constraints for UTypes&amp;&amp;... overloads (Status: C++23)">3121</a><sup><a href="https://cplusplus.github.io/LWG/issue3121" title="Latest snapshot">(i)</a></sup>.
</p>

<p><i>[2018-08 Batavia Monday issue prioritization]</i></p>

<p>Priority set to 0, status to 'Tentatively Ready'. Alisdair to write a paper about
SFINAE constraints on the Allocator-aware tuple constructors.</p>

<p><i>[2018-08 Batavia Friday]</i></p>

<p>Tim Song found a 3-element case of this issue. Status back to 'Open'</p>
<p><code>tuple&lt;any,any,any&gt;(allocator_arg_t, a, tuple)</code></p>

<p><i>[2018-09 Reflector prioritization]</i></p>

<p>Set Priority to 3</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>

<ol>
<li><p>Modify 22.4.4.2 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> as indicated:</p>
<blockquote>
<pre>
template&lt;class... UTypes&gt; explicit(<i>see below</i>) constexpr tuple(UTypes&amp;&amp;... u);
</pre>
<blockquote>
<p>
-9- <i>Effects:</i> Initializes the elements in the tuple with the corresponding value in
<code>std::forward&lt;UTypes&gt;(u)</code>.
<p/>
-10- <i>Remarks:</i> This constructor shall not participate in overload resolution unless
<code>sizeof...(Types) == sizeof...(UTypes)</code> and <code>sizeof...(Types) &gt;= 1</code> and
<code>is_constructible_v&lt;T<sub><i>i</i></sub>, U<sub><i>i</i></sub>&amp;&amp;&gt;</code> is <code>true</code>
for all <code><i>i</i></code> <ins>and <code>(sizeof...(Types) != 2 || !is_same_v&lt;remove_cvref_t&lt;U<sub>0</sub>&gt;,
allocator_arg_t&gt;)</code></ins>. The expression inside <code>explicit</code> is equivalent to:
<p/>
<code>!conjunction_v&lt;is_convertible&lt;UTypes, Types&gt;...&gt;</code>
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-08-20; LWG telecon]</i></p>

<p>Status changed to Tentatively Resolved, by <a href="lwg-defects.html#3121" title="tuple constructor constraints for UTypes&amp;&amp;... overloads (Status: C++23)">3121</a><sup><a href="https://cplusplus.github.io/LWG/issue3121" title="Latest snapshot">(i)</a></sup>.</p>

<p><i>[2021-10-23 Resolved by <a href="lwg-defects.html#3121" title="tuple constructor constraints for UTypes&amp;&amp;... overloads (Status: C++23)">3121</a><sup><a href="https://cplusplus.github.io/LWG/issue3121" title="Latest snapshot">(i)</a></sup>, approved at October 2021 virtual plenary. Status changed: Tentatively Resolved &rarr; Resolved.]</i></p>



<p id="res-3155"><b>Proposed resolution:</b></p>
<p>This issue is resolved by the resolution of issue <a href="lwg-defects.html#3121" title="tuple constructor constraints for UTypes&amp;&amp;... overloads (Status: C++23)">3121</a><sup><a href="https://cplusplus.github.io/LWG/issue3121" title="Latest snapshot">(i)</a></sup>.</p>





</body>
</html>
