The tuple is not built in order?

The following program :

#include <iostream> #include <tuple> struct A { A() { std::cout << "A constructor\n"; } }; struct B { B() { std::cout << "B constructor\n"; } }; int main() { std::tuple<A, B> t; } 

gives different conclusions on different compilers:

 # libstdc++ B constructor A constructor # libc++ A constructor B constructor 

It seems strange ... I thought that the standard would guarantee that the elements of the tuple would be constructed in the order, for example, A, B, ..., Y, Z?

+7
c ++ constructor stdtuple
Aug 24 '15 at 22:33
source share
2 answers

The construction order of std::tuple is currently not specified .

A proposal for a specific decision on his order was submitted to the committee, but until then it should not be relied on.

+5
Aug 26 '15 at 12:01
source share

As you saw, the standard does not define the order here. I saw this happening in reverse order, but basically the compiler could do whatever it wanted. Worse, your request for a “standardized constructor” will not flourish because this problem is not specific to constructors: all function arguments work this way!

Consider the following example:

 bool putOnTheSpaceSuits() { /* ... */ } bool openTheAirlock() { /* ... */ } void tryGoIntoSpace(bool spaceSuitsOn, bool airlockOpen) { if(spaceSuitsOn && airlockOpen) { spacewalk(); } } 

What happens when we run tryGoIntoSpace(putOnTheSpaceSuits(), openTheAirlock()) ? On my machine, openTheAirlock() is first evaluated, dropping our unprotected astronauts into space. Unfortunately,

The original question uses two implicit conversions; this is equivalent to std::tuple<X,Y> t(X(1),Y(2)); . You can see the same effect with any random free function that takes X and Y :

 void frob(X x, Y y) { /* ... */ } frob(X(1), Y(2)); // It unspecified, but I bet Y(2) will happen first here. 

See for yourself: http://coliru.stacked-crooked.com/a/e4142f3c8342ebf2

The fact that you are using the recursive-template constructor of tuples is not appropriate here; all C ++ functions are similar. Ideally, your function arguments should not have interesting mutually interacting side effects, but if this is not possible, you need to place an order yourself:

 X x(1); Y y(2); std::tuple<X,Y> t(x, y); 
+2
Aug 25 '15 at 8:42
source share



All Articles