Подтвердить что ты не робот

Typedef и использование объявления для такого же имени в той же области

Я просмотрел стандарт С++ 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 Каждая декларация использования - это объявление [...]

Возможно, что-то мне не хватает в стандарте, который объясняет это поведение (или я слишком устал, чтобы видеть очевидное), но я не могу найти его.

Спасибо.

4b9b3361

Ответ 1

Это право и то, что вы показали, делает код недействительным. Также есть 3.3.1p4, что делает его недействительным (см. 7.3.3p13).

Для теста реальности я тестировал ICC и отклонял его, как ожидалось.