[dcl.fct.def] p2 states:
The type of a parameter or the return type for a function definition shall not be an incomplete or abstract (possibly cv-qualified) class type in the context of the function definition unless the function is deleted.
And [class.mem] p7 states:
A class is considered a completely-defined object type (or complete type) at the closing }
of the class-specifier. The class is regarded as complete within its complete-class contexts; otherwise it is regarded as incomplete within its own class member-specification.
Given this code:
struct S
{
// S is incomplete
S f() { /* S is complete in a function body */ return S(); }
// S is incomplete
};
// S is complete
A complete-class context notably does not include the decl-specifier-seq of the function definition, nor does it include the declarator of the function, however, every compiler says this is ok. What wording allows this, as I cannot find it?
The very first item at the referred to link:
A complete-class context of a class is a
- function body ([dcl.fct.def.general]),
So within the function body of any method is considered a complete-class context. The "context of a function definition" is synonymous with the function body, as far as I can tell -- as opposed to the context of a function declaration, where the return type is not required to be complete.
I think that the compiler first finds tokens lex.phases 1.7 S
class (with all of its members declared) and f
member function (with just declaration, which includes the return type). Then, they are analyzed.
By the time the function body of f
is analyzed the S
class was analyzed first and considered as complete, because it has the member-function defined (the function boby is there, will be analyzed later).
Now S
is complete, f
can use return S()
.
But it his other case:
struct S {
decltype(S{}) f() { return S(); }
};
the compiler wants to find the type of S
by decltype
so as to regard the token (the return type of f
) and fails because the };
class-ending is not reached yet.