<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2528: Order of std::tuple construction unspecified</title>
<meta property="og:title" content="Issue 2528: Order of std::tuple construction unspecified">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2528.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#New">New</a> status.</em></p>
<h3 id="2528"><a href="lwg-active.html#2528">2528</a>. Order of <code>std::tuple</code> construction unspecified</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#New">New</a>
 <b>Submitter:</b> Brian Rodriguez <b>Opened:</b> 2015-08-25 <b>Last modified:</b> 2017-02-19</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#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The <code>std::tuple</code> order of element construction is unspecified. It is either in the same order of the type list or in reverse. 
<p/>
Consider the following program:
</p>
<blockquote><pre>
#include &lt;iostream&gt;
#include &lt;tuple&gt;

struct X 
{
  X(int) { std::cout &lt;&lt; "X constructor\n"; }
};

struct Y 
{
  Y(int) { std::cout &lt;&lt; "Y constructor\n"; }
};

int main()
{
  std::tuple&lt;X, Y&gt; t(1, 2);
}
</pre></blockquote>
<p>
Here is a <a href="http://coliru.stacked-crooked.com/a/764d0477523ba249">link</a> to two sample compilations. The first uses 
libstdc++ and constructs in reverse order, and the second uses libc++ and constructs in in-order. 
<p/>
A <code>std::tuple</code> mimics both a struct and type-generic container and should thus follow their standards. Construction is 
fundamentally different from a function call, and it has been historically important for a specific order to be guaranteed; 
namely: whichever the developer may decide. Mandating construction order will allow developers to reference younger elements 
later on in the chain as well, much like a struct allows you to do with its members.
<p/>
There are implementation issues as well. Reversed lists will require unnecessary overhead for braced-initializer-list initialization.  
Since lists are evaluated from left to right, the initializers must be placed onto the stack to respect the construction order. 
This issue could be significant for large tuples, deeply nested tuples, or tuples with elements that require 
many constructor arguments.
<p/>
I propose that the <code>std::tuple&lt;A, B, ..., Y, Z&gt;</code>'s constructor implementation be standardized, and made to construct 
in the same order as its type list e.g. <code>A{}, B{}, ..., Y{}, Z{}</code>.
</p>

<p>
<b>Daniel:</b>
<p/>
When <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3140.html">N3140</a> became accepted, wording had been
added that gives at least an indication of requiring element initialization in the order of the declaration of the template
parameters. This argumentation can be based on 22.4.4.2 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> p3 (emphasize mine):
</p>
<blockquote><p>
-3- In the constructor descriptions that follow, let <code><i>i</i></code> be in the range <code>[0,sizeof...(Types))</code> 
<span style="color:#C80000;font-weight:bold">in order</span>, 
<code><i>Ti</i></code> be the <code><i>i<sup>th</sup></i></code> type in <code>Types</code>, and <code><i>Ui</i></code> be the 
<code><i>i<sup>th</sup></i></code> type in a template parameter pack named <code>UTypes</code>, where indexing is
zero-based.
</p></blockquote>
<p>
But the current wording needs to be improved to make that intention clearer and an issue like this one is necessary to be sure that
the committee is agreeing (or disagreeing) with that intention, especially because N3140 didn't really point out the relevance of the element
construction order in the discussion, and because not all constructors explicitly refer to the ordered sequence of numbers generated
by the variable <code><i>i</i></code> (The move constructor does it right, but most other don't do that). 
</p>

<p><i>[2017-02-12, Alisdair comments]</i></p>

<p>
Note that this issue should not be extended to cover the assignment operators,
as implementations may want the freedom to re-order member-wise assignment
so that, for example, all potentially-throwing assignments are performed before
non-throwing assignments (as indicated by the <code>noexcept</code> operator).
</p>


<p id="res-2528"><b>Proposed resolution:</b></p>





</body>
</html>
