使用模板时实际发生了什么?

时间:2015-07-06 07:57:36

标签: c++ templates

我对模板的概念略感混淆。即如果你有这样的功能:

template<typename T>
void DoubleValue(T &param)
{
    param *= 2;
}

编译器如何知道允许哪些类型传递给此函数?如果代码使用该类型,它是否使用所有已知类型进行测试?这有性能问题吗?

3 个答案:

答案 0 :(得分:9)

与Java或C#中的泛型相反(其中类型参数的行为类似于boost::any,即编译器安全的,运行时检查的void*),[类/函数]模板不是[类/函数。它用于在实例化点生成ad-hoc [类/函数](不要与对象实例化混淆)。

实例化可以是明确的:

// Hey compiler, please generate code for DoubleValue<int>.
template void DoubleValue<int>(int &param);

...或隐含的:

int main() {
    // Hey compiler, I want to call DoubleValue<float>.
    // Please generate the code if it's not done already.
    return DoubleValue(1.5f);
}

所有这些都是在编译时完成的。

答案 1 :(得分:2)

编译器在您实际使用(读取:实例化)模板之前不会执行任何操作,例如:

SomeType x;
DoubleValue(x);

此时编译器尝试为函数DoubleValue(SomeType&)生成代码。如果可以生成代码,则编译成功(在您的示例中,如果SomeType类型定义了运算符*=)。

另一个例子:

template<typename T>
void SomeFunc(T param)
{
    param.foo();
}

SomeType x;
SomeFunc(x);

如果SomeFunc有方法SomeTypefoo的实例化将会成功 - 如果没有,则编译器将退出并显示错误。有时它被称为编译时多态性

我简短:模板是一种按需生成代码的便捷方式(在实际use(读取:实例化)模板之前没有任何反应。

我希望有所帮助。

答案 2 :(得分:1)

不,它不会测试所有类型。编译器只生成您将用于处理的类型的代码,如果不可能,您将收到编译错误。模板是静态多态,用于避免为多种类型重写相同的代码 例如:

  int x=5;
  DoubleValue(x);

编译器只生成int&amp;的函数。作为签名

void DoubleValue(int &param)
{
    param *= 2;
}