2012-12-13 11 views
6

Bardzo proste pytanie. Czy to jest prawidłowe C++ 11?Niestatyczny inicjator elementu z innego niestatycznego obiektu

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

GCC (4.7.2) i Clang (3,1) zarówno przyjmuję je z pedantycznym ustawieniami:

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

Intel C++ (13.0.1.117) nie. To szczeka na int baz = bar; z:

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

Kto ma rację?

W przypadku wątpliwości, używam tego kodu jak ten, gdzie przynosi kod inicjalizacji bliżej siebie, niż przeniesienie ostatnią linię do konstruktora:

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

Odpowiedz

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.

Więc tak, to:

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

jest ważny C++ 11.

Ale bądź ostrożny o kolejności, ponieważ:

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

tak określonym w Non-static data member initializers proposal (problem 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

Dzięki. To wygląda na ostateczne. Co jednak oznacza "lub klasy wywodzącej się z tej klasy"? Jak można zainicjować element członkowski z elementem klasy pochodnej? Klasa pochodna nie została jeszcze zadeklarowana, więc nie można uzyskać do niej dostępu. –

+0

@Nikos C. "lub klasy wywodzącej się z tej klasy" odnosi się do "brace-lub-equal-initializer" co oznacza, że ​​inicjator jest tym, który jest w klasie pochodnej. Zasadniczo myślę, że oznacza to, że możesz zainicjować niestatyczne elementy danych za pomocą nie statycznego elementu danych swoich klas nadrzędnych. Jest na odwrót ten, który zrozumiałeś, co ma dużo więcej sensu :) – Drax

Powiązane problemy