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.
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. –
@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). –
OK, grazie per il chiarimento! +1 –