【问题标题】:C++ evaluation order between brace-or-equal initializer and initialization-list?大括号或相等初始化程序和初始化列表之间的 C++ 评估顺序?
【发布时间】:2013-11-30 17:42:52
【问题描述】:

我有这个结构,

struct
AAA
{
    AAA() : bbb(2)
    {
        // ccc ???
    }

    int bbb = 1;
    int ccc = bbb;
};

AFAIK,如果有初始化列表:bbb(2),则表达式bbb = 1 将被忽略。然后,我不清楚ccc 最终会变成什么。

initialization-listbrace-or-equal initializer 中的哪一个会首先被评估?他们之间的规则是什么?

【问题讨论】:

  • 你为什么不检查一下?
  • @klm123 我认为具体的实现不能保证实际规则。
  • @KateGregory Hm,知道你我敢暗示你错了,但如何结合§12.6.2.9? :)
  • @JoachimIsaksson 在 VS2013 的预发布版本中,我收到了两种操作的警告。但是,我刚刚检查了发布版本,看起来只有 :() 发生了,而非静态成员 init 没有发生。无法替代测试:-)

标签: c++ c++11 initialization operator-precedence


【解决方案1】:

C++11 draft §12.6.2.9 说;

如果给定的非静态数据成员同时具有 大括号或相等初始化器和一个内存初始化器,初始化 执行由 mem-initializer 指定的,并且非静态 数据成员的大括号或相等初始化器被忽略。

[示例:给定

struct A {
  int i = /∗ some integer expression with side effects ∗/ ; 
  A(int arg) : i(arg) { }
  // ...
};

A(int) 构造函数将简单地将 i 初始化为 arg 的值, 并且 i 的大括号或相等初始化器中的副作用不会出现 地方。 —结束示例]

由于添加此规则后按声明顺序(第 12.6.2.10 节)进行初始化,bbbccc 的值都将为 2。

【讨论】:

  • 我认为紧随其后的段落更相关。 p9 实际上并没有说明 bbb 和 ccc 之间的初始化顺序,它只是说 bbb 没有初始化两次。
  • @hvd 引用问题Which one of initialization-list or brace-or-equal initializer would be evaluated first?,尽管我同意这两条规则都很重要。
  • @JoachimIsaksson 啊,我知道你是如何阅读这个问题的。我认为 OP 的意思是初始化列表 (bbb) 或大括号或等式初始化程序 (ccc),而不是初始化列表 (bbb) 或大括号或等式初始化程序 (bbb, ccc)。
  • bbb=1 被忽略时,顺序很明显,bbb=2 然后ccc=bbb 所以,ccc=2——我认为通过这一段 (9),排序没有歧义。
  • @MM。 p9 没有说“然后”,而是 p10 说的。如果颠倒 bbb 和 ccc 的声明,首先运行 ccc=bbb(未定义的行为,实际上将 ccc 设置为不可预测的值),然后才 bbb=2。
【解决方案2】:

规则总是总是按照声明的顺序初始化字段,C++11 没有改变这一点。这意味着bbb 的初始化程序首先运行,然后ccc 的初始化程序运行。无论是在字段上指定初始化器还是作为构造函数的一部分都没有关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 2017-04-03
    • 2015-06-04
    • 2018-12-11
    • 1970-01-01
    • 2023-03-03
    • 2010-11-17
    相关资源
    最近更新 更多