Я пытался использовать неполный тип в спецификаторе вложенного имени следующим образом:
class A;
int b= A::c; // error: incomplete type ‘A’ used in nested name specifier
class A {
static const int c=5;
};
Об этом ничего не говорится в рабочем проекте 3.4.3 / 1 N3797:
На имя класса, члена пространства имен или перечислителя можно сослаться
после того, как оператор разрешения :: объема (5.1) применяется к
спецификатор nested-name, который обозначает его класс, пространство имен или
перечисление
Так зависит ли это поведение от реализации?
В стандарте есть несколько мест, которые неявно подразумевают, что ваш код некорректен, но приведенная ниже цитата говорит сама за себя:
3.3.2p6
Точка декларации[basic.scope.pdecl]
После точки объявления члена класса, имя члена можно искать в области видимости его класса.
Проблема с вашим кодом не в том, что вы пытаетесь найти внутри тела неполный тип, проблема в том, что вы можете ссылаться только на имя члена класса после это было объявлено.
Поскольку ваше предварительное объявление (конечно) не содержит ни одного члена с именем с, неправильно называть такое имя.
Диагностика, выданная обоими НКУ а также лязг когда вас кормят, ваш код несколько вводит в заблуждение, и, честно говоря, я чувствую, что сообщение об ошибке в порядке.
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
};