Я искал стандарт C ++ 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», что, кажется, указывает на то, что имеет тип int и typedef преобладает. cl генерирует исполняемый файл, печатает «class a_ns :: a_t», что, кажется, указывает на то, что Visual Studio больше понравилось объявление об использовании.
Я ожидаю, что код не будет компилироваться в соответствии со следующими стандартными выдержками. Я ожидаю ошибку, похожую на «цель использования декларации конфликтует с объявлением уже в области видимости».
7.1.3.6 Аналогично, в данной области видимости класс или перечисление не должны объявляться с тем же именем, что и имя-типа-определения, объявленное в
эта область и относится к типу, отличному от класса или перечисления
сам.7.3.3.1 Объявление-использование вводит имя в декларативную область, в которой появляется объявление-использование.
7.3.3.2 Каждое объявление об использовании является объявлением […]
Возможно, в стандарте мне чего-то не хватает, что объясняет это поведение (или я слишком устал, чтобы видеть очевидное), но я не могу этого найти.
Спасибо.
Это верно, и то, что вы показали, делает код недействительным. Существует также 3.3.1p4, что также делает его недействительным (см. 7.3.3p13).
Для теста реальности я протестировал с ICC, и он отклонил его, как и ожидалось.
Других решений пока нет …