简体   繁体   English

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

[英]Non-static member initializer from another non-static

Very simple question. 很简单的问题。 Is this valid C++11? 这是有效的C ++ 11吗?

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

GCC (4.7.2) and Clang (3.1) both accept it with the pedantic settings: GCC(4.7.2)和Clang(3.1)都接受了迂腐的设置:

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

Intel C++ (13.0.1.117) does not. 英特尔C ++(13.0.1.117)没有。 It barks at int baz = bar; 它咆哮在int baz = bar; with: 有:

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

Who is right? 谁是对的?

In case you wonder, I use this for code like this, where it brings initialization code closer together, rather than moving the last line into the constructor: 如果您想知道,我将此用于此类代码,它将初始化代码放在一起,而不是将最后一行移动到构造函数中:

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 An id-expression that denotes a non-static data member or non-static member function of a class can only be used: 5.1p12只能使用表示非静态数据成员或类的非静态成员函数的id表达式

  • as part of a class member access (5.2.5) in which the object expression refers to the member's class or a class derived from that class, or 作为类成员访问(5.2.5)的一部分,其中对象表达式引用成员的类或从该类派生的类,或者
  • to form a pointer to member (5.3.1), or 形成指向成员(5.3.1)的指针,或
  • in a mem-initializer for a constructor for that class or for a class derived from that class (12.6.2), or mem-initializer中 ,用于该类的构造函数或从该类派生的类(12.6.2),或者
  • in a brace-or-equal-initializer for a non-static data member of that class or of a class derived from that class (12.6.2), or 用于该类的非静态数据成员或从该类派生的类(12.6.2) 大括号或等于初始化程序 ,或者
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand. 如果该id-expression表示非静态数据成员,则它出现在未评估的操作数中。

So yes, this : 所以是的,这个:

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

is valid C++11. 是有效的C ++ 11。

But be carefull about order because : 但要小心订单,因为:

12.6.2p10 In a non-delegating constructor, initialization proceeds in the following order: 12.6.2p10在非委托构造函数中,初始化按以下顺序进行:

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list. 首先,仅对于派生程度最高的类(1.8)的构造函数,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中“左 - to-right“是派生类base-specifier-list中基类出现的顺序。
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers). 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何)。
  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers). 然后, 非静态数据成员按照它们在类定义中声明的顺序进行初始化 (同样不管mem-initializers的顺序如何)。
  • Finally, the compound-statement of the constructor body is executed 最后,执行构造函数体的复合语句

So as specified in the Non-static data member initializers proposal (Problem 3) : 因此,在非静态数据成员初始化程序提议 (问题3)中指定:

A third issue is that class-scope lookup could turn a compile-time error into a run-time error: 第三个问题是类范围查找可能会将编译时错误转换为运行时错误:

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

(Unless caught by the compiler, i might be intialized with the undefined value of j.) (除非被编译器捕获,否则我可能会使用未定义的j值进行初始化。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM