Я просмотрел стандарт С++ 11 (ну, проект n3242) и интернет, но не смог найти точного ответа. Код ниже компилируется с помощью clang 3.2 и g++ 4.7.2, а также Visual Studio 2010, но я ожидал бы получить ошибку.
#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;
}
Построено с помощью
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 и g++ сгенерированные исполняемые файлы печатают "i", что указывает на то, что a имеет тип int и преобладает typedef. cl сгенерированный исполняемый файл prints "class a_ns:: a_t", который, как представляется, указывает, что Visual Studio больше понравилось использование объявления.
Я бы ожидал, что код не будет компилироваться в соответствии со следующими стандартными выдержками. Я ожидаю ошибку, похожую на "цель использования конфликтов объявлений с объявлением уже в области видимости".
7.1.3.6 Аналогично, в заданной области класс или перечисление не должны быть объявлены с тем же именем, что и имя typedef, которое объявлено в эта область и относится к типу, отличному от класса или перечисления сам по себе.
7.3.3.1 Использование-декларация вводит имя в декларативный регион, в котором появляется декларация использования.
7.3.3.2 Каждая декларация использования - это объявление [...]
Возможно, что-то мне не хватает в стандарте, который объясняет это поведение (или я слишком устал, чтобы видеть очевидное), но я не могу найти его.
Спасибо.