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>::type的f2,a<T>必须是完整的类型,然后导致隐式实例.
当代码引用需要完全定义类型的上下文中的模板时,或者当类型的完整性影响代码,并且尚未显式实例化此特定类型时,将发生隐式实例化.例如,构造此类型的对象时,而不是构造指向此类型的指针时.
这适用于类模板的成员:除非在程序中使用该成员,否则它不会实例化,也不需要定义.
所以给定f2<int>(1);,a<int>将被实例化然后导致编译错误.