Tuple isn't being constructed in order?

前端 未结 2 1425
半阙折子戏
半阙折子戏 2020-12-19 07:37

The following program:

#include 
#include 

struct A {
    A() { std::cout << \"A constructor\\n\"; }
};

struct B {
    B         


        
相关标签:
2条回答
  • 2020-12-19 08:27

    std::tuple construction order is currently unspecified.

    A proposal for a concrete decision on its order has been submitted to the committee but until then the order should not be relied on.

    0 讨论(0)
  • 2020-12-19 08:28

    As you've seen, the standard does not define an ordering here. I've only seen it happen in reverse order, but in principle a compiler could do anything it wanted. Worse, your request for a "standardized constructor" will not prosper, because this issue isn't specific to constructors: all function arguments work this way!

    Consider this 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 evaluated first, dumping our unprotected astronauts into space. Oops!

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

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

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

    The fact that you're using a recursively-templated tuple constructor isn't relevant here; all C++ functions are alike. Ideally your function arguments should not have interesting, mutually-interacting side effects, but if that's impossible, you have to do the ordering yourself:

    X x(1);
    Y y(2);
    std::tuple<X,Y> t(x, y);
    
    0 讨论(0)
提交回复
热议问题