来自另一个非静态的非静态成员初始值设定项

Non-static member initializer from another non-static

本文关键字:静态成员 另一个 静态      更新时间:2023-10-16

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

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

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

-std=c++11-墙-W-迂腐

Intel c++(13.0.1.117)没有。它对着int baz = bar;吠叫:

error:非静态成员引用必须相对于特定对象

谁是对的?

如果你想知道的话,我用它来处理这样的代码,它将初始化代码紧密地结合在一起,而不是将最后一行移动到构造函数中:

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

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

  • 作为类成员访问(5.2.5)的一部分,其中对象表达式引用成员的类或从该类派生的类,或
  • 形成指向成员(5.3.1)的指针,或
  • 在该类或从该类派生的类的构造函数的mem初始值设定项中(12.6.2),或
  • 大括号或相等的初始值设定项中,用于该类或从该类派生的类的非静态数据成员等级(12.6.2),或
  • 如果该id表达式表示非静态数据成员,并且它出现在未赋值的操作数中

所以是的,这个:

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

是有效的C++11。

但要小心订单,因为:

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

  • 首先,仅对于派生类最多的构造函数(1.8),虚拟基类在中初始化它们在基类的有向无环图的深度优先从左到右遍历上出现的顺序,其中"从左到右"是派生类基类说明符列表中基类的出现顺序
  • 然后,直接基类按照出现在基类说明符列表中的声明顺序进行初始化(不管mem初始化程序的顺序如何)
  • 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样,与mem初始化器的顺序无关)
  • 最后,执行构造函数主体的复合语句

因此,如非静态数据成员初始化程序提案(问题3)中所述:

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

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

(除非被编译器捕获,否则i可能会被初始化为未定义的值j。)