When type is used as the template argument (including default template argument), it's not required to be complete type.
A template argument for a type template parameter must be a type-id, which may name an incomplete type:
So for f1
, the default template argument is a<T>
and it doesn't have to be complete. Given f1<int>(1);
a<int>
doesn't need to be instantiated.
But when you refer to the member of the class template, as the default template argument typename a<T>::type
of f2
, a<T>
has to be complete type and then cause implicit instantiation.
When code refers to a template in context that requires a completely defined type, or when the completeness of the type affects the code, and this particular type has not been explicitly instantiated, implicit instantiation occurs. For example, when an object of this type is constructed, but not when a pointer to this type is constructed.
This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.
So given f2<int>(1);
, a<int>
will be instantiated and then cause the compilation error.