【问题标题】:Order of evaluation in initializer_list c++11initializer_list c ++ 11中的评估顺序
【发布时间】:2015-07-10 06:17:32
【问题描述】:

在下面的代码中,是否需要在f2 之前调用f1(反之亦然)还是未指定?

int f1();
int f2();

std::initializer_list<int> list { f1(), f2() };

【问题讨论】:

标签: c++ c++11


【解决方案1】:

这是 C++ 标准中一个有趣的角落,其中明确定义了执行顺序。第 8.5.4 节 [dcl.init.list],第 4 段:

在花括号初始化列表的初始化列表中,初始化子句,包括任何由包扩展 (14.5.3) 产生的子句,按照它们出现的顺序进行评估。也就是说,与给定初始化子句关联的每个值计算和副作用都在初始化器列表的逗号分隔列表中与任何初始化子句相关联的每个值计算和副作用之前进行排序。

所以在初始化列表中,函数调用是从左到右计算的。

【讨论】:

  • 为了完整起见,可能值得注意的是,这与未指定订单的h(f1(),f2()) 形成直接对比,(然后还有更多错误会导致h(f1(), f2(new X())) 的潜在订单new X()可能会被评估,然后调用 f1() 并引发异常,因此 X 被泄露...)
  • @MichaelAnderson:嗯,这是真的。它仅适用于初始化列表。但这就是问题所在。我确实试图暗示这种行为是异常明确的。 (还为内置逗号运算符指定了求值顺序,但正如您所注意到的,为函数调用中的参数指定了求值顺序。)
  • 我在想 C++11 之前的区别,我可能会调用一个函数来使用多个 ints 使用 vargs 或像 fn(f1(),f2(),f3()) 这样的重载,并且需要注意顺序,但是在 C++11 中,我可以使用初始化列表 fn( { f1(), f2(), f3() } ) 并保证顺序。当然,初始化列表的用途不止于此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多