c++ scope language-lawyer

c++ - Orden de inicialización variable variable de clase



scope language-lawyer (4)

Entonces, ¿podría alguien decirme por qué?

Esto se establece claramente en basic.scope.class/4 , énfasis mío:

El alcance potencial de una declaración que se extiende hasta el final de una definición de clase o más allá de ella también se extiende a las regiones definidas por sus definiciones de miembros, incluso si los miembros están definidos léxicamente fuera de la clase (esto incluye definiciones de miembros de datos estáticos, definiciones de clases anidadas, y las definiciones de funciones miembro, incluido el cuerpo de la función miembro y cualquier parte de la parte declaradora de dichas definiciones que sigue al identificador-id, incluida una cláusula-declaración-parámetro y cualquier argumento predeterminado.

Así, cuando tengas

int A::a = 200; int a = 100; int A::b = a; // note the ''::'' scope resolution operator // OUTPUT: 200

a realidad se refiere a A::a porque el alcance de la clase se extiende por A::b .

A diferencia de si tiene:

int A::a = 200; int a = 100; int b = a; // note b is not A::b // i.e. without the ''::'', scope resolution operator // OUTPUT: 100

a se referiría a (global) ::a ya que b no es miembro de la class A ,
es decir, no hay extensión de alcance de clase.

Tengo una clase A que tiene dos variables estáticas. Me gustaría inicializar una con otra variable estática no relacionada, así:

#include <iostream> class A { public: static int a; static int b; }; int A::a = 200; int a = 100; int A::b = a; int main(int argc, char* argv[]) { std::cout << A::b << std::endl; return 0; }

La salida es 200. Entonces, ¿alguien podría decirme por qué?


Eso es correcto de acuerdo con las reglas de búsqueda. [basic.lookup.unqual]/13 dice:

Un nombre utilizado en la definición de un miembro de datos estáticos de la clase X (después del id. Calificado del miembro estático) se busca como si el nombre se usara en una función miembro de X. [Nota: [class.static.data ] describe con más detalle las restricciones en el uso de nombres en la definición de un miembro de datos estáticos. - nota final]

Debido a que la a no calificada se busca como si estuviera dentro de una función miembro, primero debe encontrar el miembro A::a . El orden de inicialización de A::a y A::b no afecta la búsqueda, aunque afecta la definición del resultado.


Porque la búsqueda de nombre resuelve la a como A::a . Si desea hacer esto, deberá resolver el alcance manualmente:

int A::b = ::a; // ^ Global scope resolution

Ejemplo vivo


c++draft/class.static

Si se usa un id no calificado en la definición de un miembro estático que sigue al id . Declarador del miembro , y la búsqueda de nombres ([basic.lookup.unqual]) encuentra que el id no calificado se refiere a un miembro estático , un enumerador o un tipo anidado de la clase del miembro (o de una clase base de la clase del miembro), el id no calificado se transforma en una expresión de id calificado en la que el especificador de nombre anidado nombra el ámbito de la clase desde el cual se hace referencia al miembro. [Nota: Consulte [expr.prim.id] para conocer las restricciones en el uso de miembros de datos no estáticos y funciones de miembros no estáticos. - nota final]

Dice que el id. No calificado se transforma en una expresión de id calificado en su situación.

int A::b = a;

Puede establecer ID calificado pero no tiene un especificador de nombre anidado como este.

int A::b = ::a;