功能模板与未使用的模板参数

oli*_*ist 11 c++ templates instantiation implicit-instantiation

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;
}
Run Code Online (Sandbox Code Playgroud)

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

son*_*yao 15

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

类型模板参数的模板参数必须是type-id,可以命名不完整的类型:

因此f1,默认模板参数是a<T>,并且不必完整.给定f1<int>(1); a<int>不需要实例化.

但是,当你指的是类模板的成员,默认模板参数typename a<T>::typef2,a<T>必须是完整的类型,然后导致隐式实例.

当代码引用需要完全定义类型的上下文中的模板时,或者当类型的完整性影响代码,并且尚未显式实例化此特定类型时,将发生隐式实例化.例如,构造此类型的对象时,而不是构造指向此类型的指针时.

这适用于类模板的成员:除非在程序中使用该成员,否则它不会实例化,也不需要定义.

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