This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
std::tuple
construction unspecifiedSection: 22.4.4.2 [tuple.cnstr] Status: New Submitter: Brian Rodriguez Opened: 2015-08-25 Last modified: 2017-02-19
Priority: 3
View other active issues in [tuple.cnstr].
View all other issues in [tuple.cnstr].
View all issues with New status.
Discussion:
The std::tuple
order of element construction is unspecified. It is either in the same order of the type list or in reverse.
#include <iostream> #include <tuple> struct X { X(int) { std::cout << "X constructor\n"; } }; struct Y { Y(int) { std::cout << "Y constructor\n"; } }; int main() { std::tuple<X, Y> t(1, 2); }
Here is a link to two sample compilations. The first uses libstdc++ and constructs in reverse order, and the second uses libc++ and constructs in in-order.
Astd::tuple
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.
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.
I propose that the std::tuple<A, B, ..., Y, Z>
's constructor implementation be standardized, and made to construct
in the same order as its type list e.g. A{}, B{}, ..., Y{}, Z{}
.
Daniel:
When N3140 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 [tuple.cnstr] p3 (emphasize mine):-3- In the constructor descriptions that follow, let
i
be in the range[0,sizeof...(Types))
in order,Ti
be theith
type inTypes
, andUi
be theith
type in a template parameter pack namedUTypes
, where indexing is zero-based.
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 i
(The move constructor does it right, but most other don't do that).
[2017-02-12, Alisdair comments]
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 noexcept
operator).
Proposed resolution: