Ответ 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
};