template<typename T>
struct a
{
using type = int;
typename T::type i;
};
template<typename T, typename = a<T>>
void f1(T) {}
template<typename T, typename = typename a<T>::type>
void f2(T) {}
int main()
{
f1<int>(1); // ok
f2<int>(1); // error
return 0;
}
An instantiation of a<int>
should be an error because int::type
is illegal. But it seems that f1<int>
can't cause the instantiation of a<T>
, but f2<int>
can. What's the reason?
When type is used as the template argument (including default template argument), it's not required to be complete type.
So for
f1
, the default template argument isa<T>
and it doesn't have to be complete. Givenf1<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
off2
,a<T>
has to be complete type and then cause implicit instantiation.So given
f2<int>(1);
,a<int>
will be instantiated and then cause the compilation error.