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