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

Неполный тип в вложенном указателе имени

Я попытался использовать неполный тип в вложенном спецификаторе имен следующим образом:

class A;

int b= A::c; // error: incomplete type ‘A’ used in nested name specifier

class A {
    static const int c=5;
};

В рабочем документе N3797 № 3.4.3/1 ничего не говорится:

Название члена класса или пространства имен или перечислителя может быть передано после того, как оператор разрешения области (5.1), примененный к nested-name-specifier, который обозначает его класс, пространство имен или Перечисление

Итак, зависит ли эта реализация?

4b9b3361

Ответ 1

Введение

В стандарте есть несколько мест, которые неявно подразумевают, что ваш код плохо сформирован, но приведенная ниже цитата говорит сама за себя:

3.3.2p6 Точка декларации [basic.scope.pdecl]

После точки объявления члена класса имя участника можно найти в области своего класса.

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

Поскольку ваша декларация forward (конечно) не вводит ни одного члена с именем c, он плохо сформирован, чтобы ссылаться на такое имя.


Вводящий в заблуждение диагностический...

Диагностика, выпущенная как gcc, так и clang при кормлении вашего кода, несколько вводит в заблуждение, и, честно говоря, я чувствую, что отчет об ошибке в порядке.

foo.cpp:3:8: error: incomplete type 'A' named in nested name specifier


Нам разрешено указывать неполный тип в вложенном имени-спецификаторе, но, как сказано; нам не разрешено ссылаться на участника, который еще не был объявлен.

плохо образованы:

class X {
  static int a[X::x];        // ill-formed, `X::x` has not yet been declared
  static int const x = 123;
};

юридический:

class X {
  int const x = 123;
  int a[X::x]; // legal, `X` is incomplete (since we are still defining it)
               //        but we can still refer to a _declared_ member of it
};