初始化列表中元素的评估顺序

Evaluation order of elements in an initializer list

为什么先调用函数 g()?我将 g() 定义为初始化列表中的第二个元素。

标准中与初始值设定项列表相关的以下引述是否相关?

§8.5.4.4: Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (§14.5.3), are evaluated in the order in which they appear.

#include <iostream>
#include <vector>

int f() { std::cout << "f"; return 0;}
int g() { std::cout << "g"; return 0;}

void h(std::vector<int> v) {}

int main() {

   h({f(), g()});
}

输出:

gf

在我看来引用是相关的(编译器看到一个初始化列表):

8.5/14,16:

The initialization that occurs in the form

T x = a;

as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.

.

.

The semantics of initializers are as follows[...]: If the initializer is a braced-init-list, the object is list-initialized (8.5.4).

std::initializer_list as function argument and Folds (ish) In C++11 中有更多详细信息)

此外,任何 {} 列表都应该排序(标准对这一事实使用了非常强烈的措辞。另请参见 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030)。

所以它是 probably a GCC bug(在 gcc v4.9.0 之后修复)。

确实,尝试了各种 GCC 版本,我得到:

GCC      with --std=c++11   without (--std=c++98)
4.7.3        fg                    gf  <-
4.8.1        fg                    gf  <-
4.8.2        fg                    gf  <-
4.9.0        fg                    gf  <-
4.9.2        fg                    fg
5.1.0        fg                    fg
5.2.0        fg                    fg
6.1.0        fg                    fg

扩展的初始化列表仅适用于 C++11,但 GCC 仍会编译代码(带有警告,例如参见 [​​=18=])。

这不是 braced-init-list,因此该规则不适用。

[C++14: 5.17/9]: A braced-init-list may appear on the right-hand side of

  • an assignment to a scalar, in which case the initializer list shall have at most a single element. The meaning of x={v}, where T is the scalar type of the expression x, is that of x=T{v}. The meaning of x={} is x=T{}.
  • an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3).