2012-12-13 30 views
6

Câu hỏi rất đơn giản. Đây có phải là C++ 11 hợp lệ không?Trình khởi tạo thành viên không tĩnh từ một số khác

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

GCC (4.7.2) và Clang (3.1) đều chấp nhận nó với các thiết lập pedantic:

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

Intel C++ (13.0.1.117) thì không. Nó barks tại int baz = bar; với:

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

Ai là đúng?

Trong trường hợp bạn tự hỏi, tôi sử dụng này cho mã như thế này, nơi mà nó mang mã khởi xích lại gần nhau, thay vì di chuyển các dòng cuối cùng vào constructor:

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

Trả lời

3

5.1p12 An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • 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
  • to form a pointer to member (5.3.1), or
  • in a mem-initializer for a constructor for that class or for a class derived from that class (12.6.2), or
  • 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
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

Vì vậy, có, điều này:

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

là hợp lệ C++ 11.

Nhưng hãy cẩn thận về trật tự vì:

12.6.2p10 In a non-delegating constructor, initialization proceeds in the following order:

  • 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.
  • 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).
  • 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).
  • Finally, the compound-statement of the constructor body is executed

Vì vậy, theo quy định tại các Non-static data member initializers proposal (Vấn đề 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.)

+0

Cảm ơn. Điều đó có vẻ dứt khoát. Mặc dù những gì có nghĩa là với "hoặc của một lớp học có nguồn gốc từ lớp đó"? Làm thế nào là nó có thể khởi tạo một thành viên với một thành viên của một lớp dẫn xuất? Lớp dẫn xuất chưa được khai báo, do đó không thể truy cập nó. –

+0

@Nikos C. "hoặc của một lớp học có nguồn gốc từ lớp đó" đề cập đến "một bộ khởi tạo dấu ngoặc đơn hoặc bằng nhau" có nghĩa là trình khởi tạo là lớp đang ở trong lớp được bảo tồn. Về cơ bản tôi nghĩ rằng nó có nghĩa là bạn có thể khởi tạo các thành viên dữ liệu không tĩnh với thành viên dữ liệu không tĩnh của các lớp cha mẹ của bạn. Đó là cách khác xung quanh bạn hiểu nó, điều này có ý nghĩa hơn nhiều :) – Drax

Các vấn đề liên quan