2012-12-13 10 views
6

Sehr einfache Frage. Ist das C++ 11 gültig?Nicht-statische Mitglied Initialisierung von einem anderen nicht-statischen

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

GCC (4.7.2) und Clang (3,1), die beide mit den pedantischen Einstellungen zu übernehmen:

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

Intel C++ (13.0.1.117) nicht. Es bellt int baz = bar; mit:

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

Wer hat recht?

Falls Sie sich fragen, ich benutze diese für Code wie diesen, wo sie näher zusammen Initialisierungscode bringt, anstatt die letzte Zeile in den Konstruktor zu bewegen:

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

Antwort

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.

Also ja, das:

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

ist gültig C++ 11. Aber

seien Sie vorsichtig über Ordnung, weil:

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

So angegeben, wie in dem 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

Dank. Das sieht definitiv aus. Was ist mit "oder einer Klasse, die von dieser Klasse abgeleitet ist" gemeint? Wie ist es möglich, ein Mitglied mit einem Mitglied einer abgeleiteten Klasse zu initialisieren? Die abgeleitete Klasse wurde noch nicht deklariert, daher ist es nicht möglich, darauf zuzugreifen. –

+0

@Nikos C. "oder einer von dieser Klasse abgeleiteten Klasse" bezieht sich auf "eine Klammer-oder-gleich-Initialisierung", was bedeutet, dass der Initialisierer derjenige ist, der in der derivierten Klasse ist. Grundsätzlich denke ich, dass es bedeutet, dass Sie nicht statische Datenelemente mit nicht statischen Datenelementen Ihrer übergeordneten Klassen initialisieren können. Es ist anders herum, als du es verstanden hast, was viel sinnvoller ist :) – Drax

Verwandte Themen