具有未使用模板参数的函数模板

function template with unused template parameter

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;
}

a<int> 的实例化应该是错误的,因为 int::type 是非法的。但是好像f1<int>不能引起a<T>的实例化,但是f2<int>可以。什么原因?

当类型用作template argument(包括默认模板参数)时,不需要是完整类型。

A template argument for a type template parameter must be a type-id, which may name an incomplete type:

因此对于 f1,默认的模板参数是 a<T>,它不必是完整的。 Given f1<int>(1); a<int> 不需要实例化。

但是当你引用class模板的成员时,作为f2的默认模板参数typename a<T>::typea<T>必须是完整类型然后原因 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.

所以给定f2<int>(1);a<int>会被实例化然后导致编译错误