非常简单的问题。这是有效的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};
答案 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值进行初始化。)