元组没有按顺序构建?

Tuple isn't being constructed in order?

以下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;
}

在不同的编译器上给出不同的输出:

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

这看起来很奇怪...我认为标准会保证元组元素按顺序构造,例如 A、B、...、Y、Z?

如您所见,标准并未在此处定义排序。我只看到它以相反的顺序发生,但原则上编译器可以做任何它想做的事情。更糟糕的是,您对 "standardized constructor" 的请求不会成功,因为这个问题并非特定于构造函数:所有函数参数都以这种方式工作!

考虑这个例子:

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

当我们 运行 tryGoIntoSpace(putOnTheSpaceSuits(), openTheAirlock()) 时会发生什么?在我的机器上,首先评估 openTheAirlock(),将我们未受保护的宇航员倾倒到 space 中。糟糕!

你原来的问题使用了两个隐式转换;它相当于 std::tuple<X,Y> t(X(1),Y(2));。您可以使用任何采用 XY:

的随机自由函数看到相同的效果
void frob(X x, Y y) { /* ... */ }

frob(X(1), Y(2)); // It's unspecified, but I bet Y(2) will happen first here.

自己看看:http://coliru.stacked-crooked.com/a/e4142f3c8342ebf2

您正在使用递归模板元组构造函数这一事实与此处无关;所有 C++ 函数都是相似的。理想情况下,你的函数参数不应该有有趣的、相互影响的副作用,但如果那不可能,你必须自己进行排序:

X x(1);
Y y(2);
std::tuple<X,Y> t(x, y);

std::tuple施工顺序目前为unspecified

已向委员会 submitted 提交了对其命令作出具体决定的提案,但在此之前不应依赖该命令。