来自另一个非静态的非静态成员初始化程序

时间:2012-12-13 15:36:51

标签: c++ gcc c++11 clang icc

非常简单的问题。这是有效的C ++ 11吗?

struct Foo {
    int bar = 1;
    int baz = bar;
};

GCC(4.7.2)和Clang(3.1)都接受了迂腐的设置:

-std=c++11 -Wall -W -pedantic

英特尔C ++(13.0.1.117)没有。它在int baz = bar;咆哮着:

error: a nonstatic member reference must be relative to a specific object

谁是对的?

如果您想知道,我将此用于此类代码,它将初始化代码放在一起,而不是将最后一行移动到构造函数中:

uint8_t colorR = -1;
uint8_t colorG = -1;
uint8_t colorB = -1;
uint8_t colorA = -1;
GLubyte RGBAVec[4] = {colorR, colorG, colorB, colorA};

1 个答案:

答案 0 :(得分:3)

  

5.1p12 id-expression 表示非静态数据成员或类的非静态成员函数只能   使用:

     
      
  • 作为类成员访问(5.2.5)的一部分,其中对象表达式引用成员的类   或从该类派生的类,或
  •   
  • 形成指向成员(5.3.1)或
  • 的指针   
  • mem-initializer 中,用于该类的构造函数或从该类派生的类(12.6.2),或
  •   
  • brace-or-equal-initializer 中,用于该类的非静态数据成员或从该类派生的类   class(12.6.2),或
  •   
  • 如果该id-expression表示非静态数据成员,并且它出现在未评估的操作数中。
  •   

是的,这个:

struct Foo {
  int bar = 1;
  int baz = bar;
};

是有效的C ++ 11。

但请小心订购,因为:

  

12.6.2p10 在非委托构造函数中,初始化按以下顺序进行:

     
      
  • 首先,仅针对派生程度最高的类(1.8)的构造函数,初始化虚拟基类   它们出现在基类的有向无环图的深度优先从左到右遍历中的顺序,   其中“从左到右”是派生类base-specifier-list中基类出现的顺序。
  •   
  • 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中   (无论mem-initializers的顺序如何)。
  •   
  • 然后,非静态数据成员按照在类定义中声明的顺序进行初始化   (再次无论mem-initializers的顺序如何)。
  •   
  • 最后,执行构造函数体的复合语句
  •   

正如Non-static data member initializers proposal(问题3)中所指定的那样:

  

第三个问题是类范围查找可能会将编译时错误转换为运行时错误:

struct S {
    int i = j; // ill-formed without forward lookup, undefined behavior with
    int j = 3;
};
     

(除非被编译器捕获,否则我可能会使用未定义的j值进行初始化。)