7

事实上 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
}
  • 那么模板究竟是什么时候被实例化的呢?

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

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

4

2 回答 2

7

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

[温度.inst]

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

结合这个关于功能的要求:

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

2在函数定义中,无论是 void declarator ;或声明者;应该是一个格式良好的函数声明,如 [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作为其参数的类型?

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

于 2021-10-20T20:36:04.987 回答
5

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

Pow<int> pi;

C++ 标准说:

17.8.1 隐式实例化 [temp.inst]

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

于 2021-10-20T20:28:55.797 回答