<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1201: Do we always want to unwrap ref-wrappers in make_tuple</title>
<meta property="og:title" content="Issue 1201: Do we always want to unwrap ref-wrappers in make_tuple">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1201.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="1201"><a href="lwg-defects.html#1201">1201</a>. Do we always want to unwrap <code>ref</code>-wrappers in <code>make_tuple</code></h3>
<p><b>Section:</b> 22.4.5 <a href="https://wg21.link/tuple.creation">[tuple.creation]</a>, 22.3 <a href="https://wg21.link/pairs">[pairs]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2009-09-05 <b>Last modified:</b> 2018-10-05</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#tuple.creation">issues</a> in [tuple.creation].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Spotting a recent thread on the boost lists regarding collapsing
optional representations in <code>optional&lt;optional&lt;T&gt;&gt;</code> instances, I wonder if
we have some of the same issues with <code>make_tuple</code>, and now <code>make_pair</code>?
</p>

<p>
Essentially, if my generic code in my own library is handed a
<code>reference_wrapper</code> by a user, and my library in turn delegates some logic
to <code>make_pair</code> or <code>make_tuple</code>, then I am going to end up with a <code>pair</code>/<code>tuple</code>
holding a real reference rather than the intended reference wrapper.
</p>

<p>
There are two things as a library author I can do at this point:
</p>

<ol style="list-style-type:lower-roman">
<li>
document my library also has the same reference-wrapper behaviour as
<code>std::make_tuple</code>
</li>
<li>
roll my own <code>make_tuple</code> that does not unwrap rereferences, a lost
opportunity to re-use the standard library.
</li>
</ol>

<p>
(There may be some metaprogramming approaches my library can use to wrap
the <code>make_tuple</code> call, but all will be significantly more complex than
simply implementing a simplified <code>make_tuple</code>.)
</p>

<p>
Now I don't propose we lose this library facility, I think unwrapping
references will be the common behaviour.  However, we might want to
consider adding another overload that does nothing special with
<code>ref</code>-wrappers.  Note that we already have a second overload of 
<code>make_tuple</code> in the library, called <code>tie</code>.
</p>

<p><i>[
2009-09-30 Daniel adds:
]</i></p>


<blockquote>
<p>
I suggest to change the currently proposed paragraph for
<code>make_simple_pair</code>
</p>

<blockquote><pre>
template&lt;typename... Types&gt;
  pair&lt;typename decay&lt;Types&gt;::type...&gt; make_simple_pair(Types&amp;&amp;... t);
</pre>
<blockquote>
<p>
<del><i>Type requirements:</i> <code>sizeof...(Types) == 2</code>.</del>
<ins><i>Remarks:</i> The program shall be ill-formed, if
<code>sizeof...(Types) != 2</code>.</ins>
</p>
<p>
...
</p>
</blockquote>
</blockquote>

<p>
or alternatively (but with a slightly different semantic):
</p>

<blockquote>
<blockquote><p>
<i>Remarks:</i> If <code>sizeof...(Types) != 2</code>, this function shall not
participate in overload resolution.
</p></blockquote>
</blockquote>

<p>
to follow a currently introduced style and because the library does
not have yet a specific "<i>Type requirements</i>" element. If such thing
would be considered as useful this should be done as a separate
issue. Given the increasing complexity of either of these wordings
it might be preferable to use the normal two-argument-declaration
style again in either of the following ways:
</p>

<ol style="list-style-type:upper-alpha">
<li>
<pre>template&lt;class T1, class T2&gt;
pair&lt;typename decay&lt;T1&gt;::type, typename decay&lt;T2&gt;::type&gt;
make_simple_pair(T1&amp;&amp; t1, T2&amp;&amp; t2);
</pre>
</li>
<li>
<pre>template&lt;class T1, class T2&gt;
pair&lt;V1, V2&gt; make_simple_pair(T1&amp;&amp; t1, T2&amp;&amp; t2);
</pre>
<blockquote><p>
Let <code>V1</code> be <code>typename decay&lt;T1&gt;::type</code> and <code>V2</code> be
<code>typename decay&lt;T2&gt;::type</code>.
</p></blockquote>
</li>
</ol>

</blockquote>

<p><i>[
2009-10 post-Santa Cruz:
]</i></p>


<blockquote><p>
Mark as Tentatively NAD Future.
</p></blockquote>

<p><i>[2018-10-05 Status to Resolved]</i></p>

<p>Alisdair notes that this is solved by CTAD that was added in C++17</p>


<p><b>Rationale:</b></p>
<p>
Does not have sufficient support at this time. May wish to reconsider for a
future standard.
</p>


<p id="res-1201"><b>Proposed resolution:</b></p>
<p>
Add the following function to 22.3 <a href="https://wg21.link/pairs">[pairs]</a> and signature in
appropriate synopses:
</p>

<blockquote><pre>
template&lt;typename... Types&gt;
  pair&lt;typename decay&lt;Types&gt;::type...&gt; make_simple_pair(Types&amp;&amp;... t);
</pre>
<blockquote>
<p>
<i>Type requirements:</i> <code>sizeof...(Types) == 2</code>.
</p>
<p>
<i>Returns:</i> <code>pair&lt;typename decay&lt;Types&gt;::type...&gt;(std::forward&lt;Types&gt;(t)...)</code>.
</p>
</blockquote>
</blockquote>

<p><i>[
Draughting note: I chose a variadic representation similar to <code>make_tuple</code>
rather than naming both types as it is easier to read through the
clutter of metaprogramming this way.  Given there are exactly two
elements, the committee may prefer to draught with two explicit template
type parameters instead
]</i></p>


<p>
Add the following function to 22.4.5 <a href="https://wg21.link/tuple.creation">[tuple.creation]</a> and
signature in appropriate synopses:
</p>

<blockquote><pre>
template&lt;typename... Types&gt;
  tuple&lt;typename decay&lt;Types&gt;::type...&gt; make_simple_tuple(Types&amp;&amp;... t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>tuple&lt;typename decay&lt;Types&gt;::type...&gt;(std::forward&lt;Types&gt;(t)...)</code>.
</p>
</blockquote>
</blockquote>





</body>
</html>
