第57课.深入理解函数模板
1.函数模板深入理解
编译器会对函数模板进行两次编译
对模板代码本身进行编译
对参数替换后的代码进行编译
注意事项:
函数模板本身不允许隐式类型转换
自动推导类型时,必须严格匹配(类型必须严格匹配)
显示类型指定时,能够进行隐式类型转换
2.多参数函数模板
函数模板可以定义任意多个不同的类型参数
template <typename T1, typename T2, typename T3>
T1 Add (T2 a, T3 b)
{
return static_cast<T1>(a + b);
}
int r = Add<int, float, double>(0.5, 0.8);
对于多参数函数模板
a.无法自动推导返回值类型(注:无法确定返回值类型时,需要人工指定)
b.可以用从左向右部分指定类型参数
//T1 = int, T2 = double, T3 = double
int r1 = Add<int>(0.5, 0.5); // 推荐
//T1 = int, T2 = float, T3 = double
int r2 = Add<int, float>(0.5, 0.5);
//T1 = int, T2 = float, T3 = float
int r3 = Add<int, float, float>(0.5, 0.5);
工程中将返回值参数作为第一类型参数。
eg:
#include <iostream>
#include <string>
using namespace std;
template
< typename T1, typename T2 >
int Add(T1 a, T2 b)
{
return static_cast<int>(a + b);
}
int main()
{
int r1 = Add(0.5, 0.8);
cout << "r1 = " << r1 << endl; // r1 = 1
return 0;
}
3.当函数重载遇见函数模板
函数模板可以像普通函数一样被重载
a.c++编译器优先考虑普通函数
b.如果函数模板可以产生一个跟好的匹配,那么选择模板
c.可以通过空模板实参列表限定编译器只匹配函数模板
int r1 = Max(1, 2);
double r2 = Max<>(0.5, 0.8); // 这里 <> 限定编译器只能匹配函数模板
eg:
#include <iostream>
#include <string>
using namespace std;
template < typename T >
T Max(T a, T b)
{
cout << "T Max(T a, T b)" << endl;
return a > b ? a : b;
}
int Max(int a, int b) // 与T Max(T a, T b)构成重载
{
cout << "int Max(int a, int b)" << endl;
return a > b ? a : b;
}
template < typename T >
T Max(T a, T b, T c)
{
cout << "T Max(T a, T b, T c)" << endl;
return Max(Max(a, b), c);
}
int main()
{
int a = 1;
int b = 2;
cout << Max(a, b) << endl; // 普通函数
cout << Max<>(a, b) << endl; // 函数模板
cout << Max(3.0, 4.0) << endl; // 函数模板
cout << Max(5.0, 6.0, 7.0) << endl; // 函数模板
cout << Max('a', 100) << endl; // 普通函数,因为函数模板自动推导时。不能隐式转换
return 0;
}