理解函数模板
理解函数模板
函数模板的意义:对类型也可以参数化
int sum(int a, int b) {
return a + b;
}
int 定死
函数模板让参数类型可变
- 函数模板 不进行编译
- 模板的实例化 在函数调用点编译
- 模板函数 需要编译
- 模板类型参数
- 模板非类型参数
- 模板的实参推演=>模板根据实参推导函数实例
- 模板的特例化(专用化)
- 函数模板、模板的特例化、非模板函数的重载关系
1 | //函数模板,不编译 |
函数的调用点,编译器用用户指定的类型,从原模版实例化一份函数代码出来
即模板函数
bool compare
{
return a > b;
}
bool compare
{
return a > b;
}
bool compare
{
return a > b;
}
此处比较的是ab的地址大小,我们应该比较字符串的内容
这个根据模板推演的模板函数不是我们想要的,因此需要我们特例化
针对compare函数模板,提供const char*的特例化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//前面还是需要函数模板
template<> //模板的专用化模板
bool compare<const char*>(const char* a, const char* b)
{
cout<<"compare<const char*>"<<endl;
return strcmp(a,b) > 0;
}
//普通函数
bool compare(const char* a, const char* b)
{
return strcmp(a,b) > 0;
}
1 | int main() { |
对于某些类型来说,依赖编译器默认实例化的模板代码,代码处理逻辑是错误的
模板的特例化(专用化)
不是编译器,而是开发者提供的1
2
3
4
5
6template<> //模板的专用化
bool compare <const char*>(const char* a, const char* b)
{
cout<<"compare<const char*>"<<endl;
return strcmp(a,b) > 0;
}
多文件
在多文件工程时,将函数定义放在test.cpp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20template<typename T> //定义一个模板参数列表
bool compare(T a, T b) { //compare是一个函数模板
cout<<"template compare"<<endl;
return a > b;
}
template<> //模板的专用化模板
bool compare<const char*>(const char* a, const char* b)
{
cout<<"compare<const char*>"<<endl;
return strcmp(a,b) > 0;
}
//普通函数
bool compare(const char* a, const char* b)
{
return strcmp(a,b) > 0;
}
test2.cpp1
2
3
4
5
6
7
8
9
10
11
12//模板声明
template<typename T> //定义一个模板参数列表
bool compare(T a, T b) ;
int main() {
compare<int>(10,20)
compare<double>(10.1,20.2)
compare(10.1,20.2)
compare<int>(10,20.1)
compare("aaa","bbb"); //无报错
compare<const char*>("aaa","bbb");//无报错,其余都报错
}
结论:
模板在跨文件时,由于模板是不编译的,即使声明了模板,也找不到对应的代码
对于特例化的模板函数,声明了模板,就能找到
也不用管那么多,模板代码放在头文件中,在源文件中进行#include包含,这样源文件一定能看见模板代码
ps:也可以让编译其对模板进行实例化c++
template bool compare<int>(int a, int b);
对这种模板函数进行实例化