Example:
class A
{
class B
{
A c;//error!A is an incomplete type
void test() { A b;/*OK,but why?*/ }
};
};
The code snippet seems strange for me,what's the difference between the two usage of A
?
[class.mem]/6 specifies that:
A class is considered a completely-defined object type (6.9) (or complete type) at the closing
}
of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
The definition of an object (as in A b;
or A c;
) requires the object to have a complete type. As the paragraph above states, the class type is incomplete within its own definition, except in certain places: namely, inside member function bodies and a few other places.
This rule makes it possible to write nontrivial code inside member functions defined inline while also prohibiting a class from containing itself (directly or indirectly).