2012-04-07 15 views
32

Accidentalmente encontré esto en uno de los códigos fuente que estaba viendo. Entonces, estoy dando un ejemplo más pequeño similar aquí.Operador de resolución de alcance

En el archivo test.h:

#include<iostream> 

class test{ 
    int i; 
public: 
    test(){} 
    //More functions here 
}; 

En el test.cpp archivo :

#include "test.h" 

int main() 
{ 
    test test1; 
    test::test test2; 
    test::test::test test3; 
    return 0; 
} 

En primer lugar, hay una razón para declarar test2 de esa manera? En segundo lugar, este código compila muy bien en g ++ versión 4.4.3 y versiones más bajas. ¿Hay algo en el estándar de C++ que indique que los operadores de resolución de alcance son ignorados cuando no hay necesidad de resolver el alcance?

Respuesta

41

Este código no es válido.

Era un error en g ++ que aceptaba el código. Consulte "g++ does not treat injected class name correctly." El error se resolvió como corregido en 2009, por lo que debe corregirse en cualquier versión reciente de g ++.

+0

Haha, incluso mejor + 1. Me dejó perplejo. –

+0

De acuerdo, +1 de hecho estoy tentado de escribir una respuesta solo para aclarar. ¡Salud, James! –

+2

+1 Buen hallazgo ... –

16

para aclarar la situación, como se especifica en § 9/2:

A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.

Sin embargo, como se especifica en §3.4.3.1/1:

If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-namespecifier is looked up in the scope of the class (10.2), except for the cases listed below.

[ ... §3.4.3.1/2]:

In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C:

— if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (Clause 9) [ ... ] the name is instead considered to name the constructor of class C.

[ ... example: ]

struct A { A(); }; 
[ ... ] 
A::A a; // error, A::A is not a type name 
struct A::A a2; // object of type A 
+0

++ 1! belleza en verdad! –

+10

@Tats_innit: Error: "++ 1": lvalue required. :-) –

+0

lolz! error :: error sintáctico en la cabeza ... ID-10-T :) buena explicación bruv! ¡ten una buena! –

Cuestiones relacionadas