2012-04-07 13 views
32

Ho accidentalmente trovato questo in uno dei codici sorgente che stavo guardando. Quindi, sto dando un esempio più piccolo simile qui.Operatore di risoluzione dell'oscilloscopio

Nel file test.h:

#include<iostream> 

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

Nel file test.cpp:

#include "test.h" 

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

Prima di tutto, c'è un motivo per dichiarare test2 in quel modo? In secondo luogo, questo codice viene compilato correttamente nella versione 4.4.3 e versioni precedenti di g ++. C'è qualcosa nello standard C++, dicendo, gli operatori di risoluzione scope vengono ignorati quando non è necessario risolvere l'ambito?

risposta

41

Questo codice non è valido.

È stato un errore in g ++ che ha accettato il codice. Vedi "g++ does not treat injected class name correctly." Il bug è stato risolto come risolto nel 2009, quindi dovrebbe essere corretto in qualsiasi versione recente di g ++.

+0

Haha, ancora meglio + 1. Mi ha fatto perplesso. –

+0

D'accordo, +1 in effetti sono tentato di scrivere una risposta solo per chiarire. Ciao James! –

+2

+1 Nice find ... –

16

Per chiarire la situazione, come specificato nel § 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.

Tuttavia, come specificato in §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! bellezza davvero! –

+10

@Tats_innit: errore: "++ 1": lvalue richiesto. :-) –

+0

lolz! errore :: errore sintattico sulla testa ... ID-10-T :) bella spiegazione bruv! buona! –