对构造函数的参数的评估顺序

时间:2013-06-29 15:05:08

标签: c++ c++11

说我有这个班:

struct A
{
  A(int, int, int) {}
};

我将它初始化为:

A{ a(), b(), c() };

功能a()b()c()都返回int。在a()之前b()b()之前应该c()之前调用吗?

我对标准中的以下段落感到困惑(8.5.4 [dcl.init.list] p4):

  

在braced-init-list的initializer-list中,initializer-clause,包括pack中的任何结果   扩展(14.5.3),按它们出现的顺序进行评估。也就是说,每个值计算和   在每个值计算和侧面之前,对与给定初始化子句相关联的副作用进行排序   与在初始化列表的逗号分隔列表中跟随它的任何initializer子句相关联的效果。   [注意:无论初始化的语义如何,此评估顺序都保持不变;例如,它适用   当initializer-list的元素被解释为构造函数调用的参数时,即使如此   通常,对呼叫的参数没有排序限制。 - 结束说明]

根据引用,函数将按它们出现的顺序调用,但是当我用我的编译器(g ++ - 4.8.1)测试它时,它没有成功。我误解了什么吗?

2 个答案:

答案 0 :(得分:6)

这是bug in GCC(感谢Casey链接)。您引用的段落通常适用于列表初始化,其中术语在第8.5.4 / 1段中非常明确地定义:

  

列表初始化是从 braced-init-list 初始化对象或引用。这样的初始化程序是   称为初始化列表,列表中逗号分隔的 initializer-clauses 称为元素   初始化列表。

没有理由相信这应该只适用于初始化列表构造函数的调用。此外,您引用的段落中的注释澄清了:

  

无论初始化的语义如何,此评估顺序都成立;例如,当初始化程序列表的元素被解释为构造函数调用的参数时,应用,即使通常对调用的参数没有排序约束。

答案 1 :(得分:2)

小心你正在处理什么。据我所知,您引用的引用仅适用于初始化列表。您正在使用的功能是统一初始化。它是初始化列表所必需的,但我怀疑它是统一初始化的。