Tuple isn't being constructed in order?

穿精又带淫゛_ 提交于 2019-11-28 03:35:48

问题


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 outputs on different compilers:

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

This seem weird... I figured the standard would have guaranteed the tuple elements be constructed in-order, e.g., A, B, ..., Y, Z?


回答1:


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.




回答2:


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);


来源:https://stackoverflow.com/questions/32192809/tuple-isnt-being-constructed-in-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!