Tuple isn't being constructed in order?

爱⌒轻易说出口 提交于 2019-11-29 10:32:12

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.

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