2013-02-27 12 views
10

Ho setacciato lo standard C++ 11 (beh, la bozza n3242) e Internet ma non sono riuscito a trovare una risposta precisa. Il codice sotto compila bene con clang 3.2 e g ++ 4.7.2 e Visual Studio 2010, ma mi aspetto di ricevere un errore.typedef e utilizzo della dichiarazione per lo stesso nome allo stesso scopo

#include <iostream> 
#include <typeinfo> 


typedef int a_t; 


namespace a_ns 
{ 
class a_t {}; 
} 


using a_ns::a_t; 


int main() 
{ 
    a_t a; 
    std::cout << typeid(a).name() << std::endl; 
    return 0; 
} 

costruiti con:

clang -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++ 
g++ -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++ 
cl -EHsc -GR a.cpp 

clang e g ++ generato eseguibili di stampa "i", che sembra indicare che il un è di tipo int e il typedef prevalso. le stampe eseguibili generate da cl "class a_ns :: a_t" che sembra indicare che a Visual Studio è piaciuta l'uso della dichiarazione di più.

Mi aspetto che il codice non venga compilato in base ai seguenti estratti standard. Mi aspetterei un errore simile a "obiettivo dell'utilizzo di conflitti di dichiarazione con la dichiarazione già in ambito".

7.1.3.6 Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.

7.3.3.1 A using-declaration introduces a name into the declarative region in which the using-declaration appears.

7.3.3.2 Every using-declaration is a declaration [...]

C'è probabilmente qualcosa che mi manca nella norma che spiega questo comportamento (o io sono troppo stanco per vedere l'ovvio), ma io non riesco a trovarlo.

Grazie.

risposta

4

Questo è giusto e ciò che è stato mostrato rende il codice non valido. C'è anche 3.3.1p4 che lo rende invalido (vedi 7.3.3p13).

Per un test di realtà, ho provato con ICC e lo rifiuta come previsto.

+0

Se il corpo di 'main()' era vuoto, anche quel programma sarebbe non valido? Il paragrafo 7.1.3/6 dice "* In un determinato ambito, un identificatore typedef non deve essere usato per ** ridefinire ** il nome di qualsiasi tipo dichiarato in tale ambito per fare riferimento a un tipo diverso. * [Esempio:' classe complex {/ ... /}; typedef int complex; // errore: redefinition' -end esempio *] "*. Nella domanda, il 'typedef' non" ridefinisce "il nome. Quando vengono spostati dopo la dichiarazione 'using', tutti i compilatori emettono un errore. –

+0

@andy se main era vuoto, sarebbe invalido, secondo le citazioni che abbiamo trovato. se anche qualche altra citazione si applica è irrilevante allora. normalmente, una ridefinizione di un nome si verifica per 'classe A {}; typedef AA; '(prima è solo un nome di classe, quindi è anche un typedef-name, il nome è ridefinito, perché in seguito c'è ancora un solo nome, ma ha entrambi gli attributi sintattici. Modello C). –

+0

OK, grazie per il chiarimento! +1 –

Problemi correlati