函数模板有一个或多个类型形参,通过为模板的每个形参提供具体的类型实参来生成具有的参数。
使用函数模板templateT function_name(T param, ...) { //user code retrun return_value; //type T } template T function_name(T param, ...) { //user code retrun return_value; //type T } template T1 function_name(T1 param1, T2 param2) { //user code retrun return_value; //type T1 }
- template 关键字将上面的代码标志为模板定义。
- template关键字后面的尖括号包围着以逗号分开的,用来创建具体函数实例的类型形参。
- T前面的关键字class表明,T是该模板的类型形参,class是表示类型的通用术语。
- 可以用关键字typename代替class来标识函数模板中的形参。
如果代码中未使用模板,就不会标志处该模板中的错误。
#include "pch.h" #include#include template T1 add(T1 param1, T2 param2) { T1 return_value{ }; return_value = static_cast (param1 + param2); return return_value; } int main() { double a{ add(4.2f, 4) }; std::cout<
使用函数模板通常会增加程序的大小,因为即使现有的函数版本可以强制转换成相应的实参而满足使用要求,但编译器仍然可能自动创建新版本。
可以通过显示地包括函数的声明,强制创建模模板的具体实例。
(待学习)
通过将特定类型作为自变量来声明模板,可以将函数模板显示实例化。 例如,以下代码是允许的:
// 函数模板实例化 templatevoid f(T) { } // 使用明确指定的模板参数类型int实例化f。 template void f (int); // 使用推导出的模板参数“char”实例化 f。 template void f(char); int main() { }
#include "pch.h" #include#include template T1 add(T1 param1, T2 param2) { T1 return_value{ }; return_value = static_cast (param1 + param2); return return_value; } template int add (int param1, int param2); template float add (float param1, int param2); int main() { std::cout << add(4.2f, 4) << std::endl; std::cout << add(3, 4) << std::endl; }
利用函数模板,您可以通过为特定类型提供函数模板的显式专用化(重写)来定义该类型的特殊行为。
template<> void MySwap(double a, double b);
此声明使你可以为 double 变量定义不同的函数。 与非模板函数一样,将应用标准类型转换 (例如将类型 float 变量转换为 double) 。
// 函数模板实例化 template使用decltype操作符void f(T t) { }; // 显示指出模板类型'char' 显式实例化 f template<> void f (char c) { } //用模板参数“double ”推断出f的显式实例。 template<> void f(double d) { } int main() { }
使用decltype操作符可以得到一个表达式的类型,因此decltype(exp)是表达式exp求值的结果的类型。
此操作符不要用于定义函数模板。
#include "pch.h" #include#include template auto add(T1 param1, T2 param2) { decltype(param1 + param2) return_value { param1 + param2 }; //decltype(类型推断表达式) return return_value; } int main() { std::cout << add(4.2f, 4) << std::endl; std::cout << add(3, 4) << std::endl; }



