Скрытие имен с помощью директивы using - PullRequest
3 голосов
/ 27 апреля 2020

Пример кода:

struct A {};
struct B { using A = A; };

int main()
{
    B b;
}

Clang компилирует его. Но G CC выдает следующую ошибку ( demo ):

объявление 'using A = struct A' меняет значение 'A'

Стандарт C ++ гласит:

Если имя класса ([class.name]) или имя перечисления ([dcl.enum]) и переменная, элемент данных, функция или перечислитель объявляются в одной и той же декларативной области (в любом порядке) с тем же именем (, исключая объявления, видимые с помощью директив using ([basi c .lookup.unqual]) ), имя класса или перечисления скрыто везде, где видна переменная, член данных, функция или имя перечислителя.

UPD.0 : благодаря Владу из Москва

Имя N, используемое в классе S, должно относиться к тому же объявлению в его контексте и при повторной оценке в завершенном объеме S. Диагностика c не требуется для нарушения это правило

Означает ли это, что поведение G CC неверно? Спасибо!

1 Ответ

3 голосов
/ 27 апреля 2020

Кажется, это ошибка g cc. В соответствии со стандартом C ++ 20 (6.3.7 Область действия класса)

2 Имя N, используемое в классе S, должно ссылаться на то же объявление в его контексте и при повторной оценке в завершенной области действия S. Для нарушения этого правила не требуется диагностика c.

В этом случае

struct A {};
struct B { using A = A; };

имя B::A относится к тому же объявлению struct A.

Вот пример из стандарта C ++, который показывает значение цитаты.

typedef char* T;
struct Y {
   T a; // error: T refers to ::T but when reevaluated is Y::T
   typedef long T;
   T b;
};
...