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

时间:2018-06-15 10:21:13

标签: 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;
}

a<int>的实例化应该是一个错误,因为int::type是非法的。但似乎f1<int>无法导致a<T>的实例化,但f2<int>可以。select datetimefromparts(2018,3,25,0,0,0,0) at TIME ZONE 'E. Europe Standard Time' select datetimefromparts(2018,3,26,0,0,0,0) at TIME ZONE 'E. Europe Standard Time' 。原因是什么?

1 个答案:

答案 0 :(得分:15)

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

  

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

因此对于f1,默认模板参数为a<T>,并且不必完整。鉴于f1<int>(1); a<int>不需要实例化。

但是,当您引用类模板的成员时,typename a<T>::type的默认模板参数f2a<T>必须是完整类型,然后导致implicit instantiation

  

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

     

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

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