Неполные типы в определениях функций-членов
[dcl.fct.def] p2 сообщает:
Тип параметра или возвращаемого типа для определения функции не должен быть неполным или абстрактным (возможно, cv-квалифицированным) типом класса в контексте определения функции, если функция не удалена.
И [class.mem] p7 заявляет:
Класс считается полностью определенным типом объекта (или полным типом) при закрытии }
спецификатора класса. Класс считается завершенным в контексте полного класса; в противном случае он считается неполным в пределах собственной спецификации члена класса.
Учитывая этот код:
struct S
{
// S is incomplete
S f() { /* S is complete in a function body */ return S(); }
// S is incomplete
};
// S is complete
контекст полного класса, в частности, не включает в себя decl-specier-seq определения функции и не включает в себя декларатор функции, однако каждый компилятор говорит, что это нормально. Какая формулировка позволяет это, поскольку я не могу найти это?
Ответы
Ответ 1
Самый первый пункт по указанной ссылке:
Полный контекст класса - это
- тело функции ([dcl.fct.def.general]),
Таким образом, в теле функции любого метода рассматривается контекст полного класса. Насколько я могу судить, "контекст определения функции" является синонимом тела функции, в отличие от контекста объявления функции, где тип возвращаемого значения не обязательно должен быть завершен.
Ответ 2
Я думаю, что компилятор сначала находит токены класса lex.phases 1.7 S
(со всеми объявленными его членами) и функции-члена f
(только с объявлением, которое включает тип возвращаемого значения). Затем они анализируются.
К тому времени, когда тело функции f
анализируется, класс S
сначала анализируется и считается завершенным, поскольку в нем определена функция-член (функция boby есть, она будет проанализирована позже).
Теперь S
завершен, f
может использовать return S()
.
Но это его другой случай:
struct S {
decltype(S{}) f() { return S(); }
};
компилятор хочет найти тип S
по decltype
, чтобы расценивать токен (возвращаемый тип f
), и терпит неудачу, потому что окончание класса };
еще не достигнуто.