我对模板的概念略感混淆。即如果你有这样的功能:
template<typename T>
void DoubleValue(T ¶m)
{
param *= 2;
}
编译器如何知道允许哪些类型传递给此函数?如果代码使用该类型,它是否使用所有已知类型进行测试?这有性能问题吗?
答案 0 :(得分:9)
与Java或C#中的泛型相反(其中类型参数的行为类似于boost::any
,即编译器安全的,运行时检查的void*
),[类/函数]模板不是[类/函数。它用于在实例化点生成ad-hoc [类/函数](不要与对象实例化混淆)。
实例化可以是明确的:
// Hey compiler, please generate code for DoubleValue<int>.
template void DoubleValue<int>(int ¶m);
...或隐含的:
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
有方法SomeType
,foo
的实例化将会成功 - 如果没有,则编译器将退出并显示错误。有时它被称为编译时多态性。
我简短:模板是一种按需生成代码的便捷方式(在实际use
(读取:实例化)模板之前没有任何反应。
我希望有所帮助。
答案 2 :(得分:1)
不,它不会测试所有类型。编译器只生成您将用于处理的类型的代码,如果不可能,您将收到编译错误。模板是静态多态,用于避免为多种类型重写相同的代码 例如:
int x=5;
DoubleValue(x);
编译器只生成int&amp;的函数。作为签名
void DoubleValue(int ¶m)
{
param *= 2;
}