模板何时实例化?

Ita*_*iwa 7 c++ template-instantiation

事实上,atemplate在使用之前不会被实例化,例如,如果我有这个类模板:

template <typename T>
struct Pow{
    T operator()(T const& x) const{ return x * x; }
};

void func(Pow<double>); // Pow<double> instantiated here?
void func(Pow<int>){}   // Pow<int> instantiated here?

int main(){
    Pow<int> pi; // instantiated here?
    func(pi); // Pow<int> instantiated here
}
Run Code Online (Sandbox Code Playgroud)
  • 那么模板具体什么时候被实例化呢?

  • 那么是在声明的Pow<int>时候实例化的吗func(Pow<int>)

  • 如果我没有使用Pow<int>inmain()那么它是否因为使用 infunc作为其参数的类型而被实例化?

Sto*_*ica 8

类模板隐式实例化的一般规则如下

[温度设置]

2除非类模板特化是声明的特化,否则当在需要完全定义的对象类型的上下文中引用特化时,或者当类类型的完整性影响程序的语义时,类模板特化会被隐式实例化。[...]

结合有关功能的要求:

[dcl.fct.def.general](强调我的)

2在函数定义中,可以使用 void 声明符;或声明者;应是格式良好的函数声明,如 [dcl.fct] 中所述。函数只能在命名空间或类范围内定义。函数定义的参数类型或返回类型不得是函数体内不完整或抽象的(可能是 cv 限定的)类类型,除非删除该函数 ([dcl.fct.def.delete]) 。

告诉我们检查您的程序所需的一切。函数声明不要求类类型完整。所以...

Pow<double>在这里实例化?

不。这是函数声明,而不是定义。它不需要参数的完整类类型。Pow<double>不是隐式实例化的。

Pow<int>在这里实例化?

是的。这是一个函数定义,因此需要实例化。

Pow<int> pi;// 在这里实例化?

由于该功能已被实例化。

那么模板具体什么时候被实例化呢?

严格要求时会影响程序的语义。

那么是在声明的Pow<int>时候实例化的吗func(Pow<int>)

什么时候func(Pow<int>)定义

如果我没有使用Pow<int>inmain()那么它是否因为使用 infunc作为其参数的类型而被实例化?

是的,因为您在函数定义中这样做了。


San*_*dro 6

在您的示例中,当编译器看到模板类的对象创建时,它就会被实例化:

Pow<int> pi;
Run Code Online (Sandbox Code Playgroud)

C++ 标准说:

17.8.1 隐式实例化[temp.inst]

1 除非类模板特化已显式实例化 (17.8.2) 或显式特化 (17.8.3),否则当在需要完全定义的对象类型的上下文中引用特化时,或者当类类型的完整性影响程序的语义......