具体来说,我说:
struct X { X(int i) { cout << i; } };
int f() { cout << 'f'; return 0; }
int g() { cout << 'g'; return 1; }
struct Z {
Z() : a(f()), b(g()) {}
X a, b;
};
int main() { Z z; cout << '\n'; }
我知道成员的构造函数保证按照struct
中定义的顺序调用,因此0
将在1
之前打印。
但是如何评价他们的论点呢?是否保证:
f0g1
?或者,或许,
fg01
和
gf01
也是有效的输出?
赞赏参考标准。
答案 0 :(得分:5)
在C++11 draft standard中,每个成员初始化程序都是一个完整表达式,因此所有副作用必须在评估下一个之前生效。
部分12.6.2
初始化基础和成员段 7 说:
[...]每个mem-initializer执行的初始化构成一个完整表达式。任何 mem-initializer中的表达式被评估为执行初始化的完整表达式的一部分。[...]
和部分1.9
计划执行段 14 说:
在每个值计算和与要评估的下一个完整表达式相关的副作用之前,对与全表达式相关的每个值计算和副作用进行排序。
12.6.2
部分的相关语法如下:
ctor-initializer:
: mem-initializer-list
mem-initializer-list:
mem-initializer ...opt
mem-initializer , mem-initializer-list ...opt
[...]
前 C ++ 11 每个 mem-initializer 作为完整表达式的相同措辞不存在,至少不是最早的可用草案标准{{ 3}}。但据我所知,我在1804中使用的逻辑同样适用于这种情况,因此我们也应该期待 C ++ 11 之前的相同行为。
答案 1 :(得分:2)
根据C ++标准
每个mem-initializer执行的初始化构成一个 充分表达。 mem-initializer中的任何表达式都被评估为 执行初始化的全表达式的一部分
首先,将执行完整表达式a(f()),然后执行完整表达式b(g())。
结果输出必须是
f0g1