什么时候实例化模板?

When a template is instantiated?

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

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
}

在你的例子中,当编译器看到你的模板对象的创建时它被实例化class:

Pow<int> pi;

C++ 标准说:

17.8.1 Implicit instantiation [temp.inst]

1 Unless a class template specialization has been explicitly instantiated (17.8.2) or explicitly specialized (17.8.3), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program...

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

[temp.inst]

2 Unless a class template specialization is a declared specialization, the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program. [...]

结合此功能要求:

[dcl.fct.def.general] (emphasis mine)

2 In a function-definition, either void declarator ; or declarator ; shall be a well-formed function declaration as described in [dcl.fct]. A function shall be defined only in namespace or class scope. The type of a parameter or the return type for a function definition shall not be a (possibly cv-qualified) class type that is incomplete or abstract within the function body unless the function is deleted ([dcl.fct.def.delete]).

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

Pow<double> instantiated here?

没有。这是一个不是定义的函数声明。它不需要参数的完整 class 类型。 Pow<double> 未隐式实例化。

Pow<int> instantiated here?

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

Pow<int> pi; // instantiated here?

由于功能已经实例化。

So when exactly the template is instantiated?

严格要求以影响程序语义的方式。

So is Pow<int> instantiated when func(Pow<int>) is declared?

func(Pow<int>)定义时

If I didn't use Pow<int> in main() then has it been instantiated because of its usage in func as the the type of its parameters?

是的,因为您是在函数 定义.

中这样做的