元组没有按顺序构建?
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));
。您可以使用任何采用 X
和 Y
:
的随机自由函数看到相同的效果
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 提交了对其命令作出具体决定的提案,但在此之前不应依赖该命令。
以下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));
。您可以使用任何采用 X
和 Y
:
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 提交了对其命令作出具体决定的提案,但在此之前不应依赖该命令。