То же имя в typedef и использование из пространства имен - PullRequest
3 голосов
/ 29 апреля 2019

Пример кода:

struct X { void f() {} };
typedef X A;

namespace N { 
    struct A { void g() {} };
};

using N::A;

int main()
{
    A a;
    a.f();
}

Этот код компилируется правильно, и A a; создает X, а не N::A.

Какое правило в стандарте охватывает это поведение?Я ожидал ошибку, что A a; будет неоднозначным.Если я назову первую структуру A вместо X и удалю typedef, я получу такую ​​ошибку.(g ++ 8,3)

1 Ответ

3 голосов
/ 29 апреля 2019

Согласно [namespace.udecl] / 1 using N::A вводит неквалифицированный A в декларативную область, в которой появляется объявление использования.

... неквалифицированный идентификатор объявляется в декларативной области, в которой декларация об использовании появляется в качестве синонима для каждого объявления, введенного декларатором использования.

Таким образом, двусмысленность совместно рассматривается [namespace.udecl] / 13

Поскольку декларация использования является декларацией, ограничения на декларации с одинаковыми именами в одном и том же декларативном регионе также применяются к декларациям использования.

и [basic.scope.declarative] / 4

Учитывая набор объявлений в одном декларативном регионе, каждый из который указывает то же безоговорочное имя,

  • они все должны относиться к одному и тому же объекту или все относятся к функциям и шаблонам функций; или
  • ровно одно объявление должно объявлять имя класса или имя перечисления, которое не является именем typedef, и все другие объявления должны ссылаться на одну и ту же переменную, нестатический член данных или перечислитель, или все они ссылаются на функции и шаблоны функций; в этом случае имя класса или имя перечисления скрыто.

Объявление typedef и объявление использования в OP не заполняют ни одну из них, поэтому пара объявлений в одном и том же декларативном регионе некорректна.

...