模板参数分为 类型形参 和 非类型形参
#include using namespace std;// T 为类型参数,N 为非类型参数,只可以当常量使用
//模板参数的缺省规则和函数参数的缺省规则一样
template
class Array
{
public:size_t capaciyt() const{return N;}private:T arr[N];
};int main()
{Array a1;Array a2;// 输出 10 20cout << a1.capaciyt() << " " << a2.capaciyt() << endl;return 0;
}
用模板可以实现通用的函数和类,但是有时想要对该模板中的某些类型进行特殊化处理,就需要使用模板特化,函数模板和类模板都可以进行特化,但通常函数模板特化可以用函数重载替代
模板特化的语法:
1. 必须要先有一个基础的函数模板或类模板
2. 模板关键字 template 后跟 <>,<> 中写出未特化的类型,都特化了就不写如果是偏特化中的满足条件特化则需要使用 typename 关键字后跟偏特化的类型
3. 函数名或类名后跟 <>,<> 中指定需要特化的类型,未特化的类型也需要写出
4. 函数名或类名、函数形参表需要和原模板保持一致
模板特化的使用:
#include using namespace std;// 定义一个通用的小于的仿函数
template
struct Less
{bool operator()(const T& x, const T& y){return x < y;}
};// 对 int* 进行特化
template<>
struct Less
{bool operator()(const int* x, const int* y){return *x < *y;}
};int main()
{// 创建匿名对象调用 less 模板,输出 1cout << Less()(1, 2) << endl;// 如果还是调用 less 模板,便只能用地址比较,可能输出 0// 通过特化后,可以用指针指向的内容进行比较,输出 1int* p1 = new int(1);int* p2 = new int(2);cout << Less()(p1, p2) << endl;return 0;
}
模板特化分为 全特化 和 偏特化(半特化)
#include using namespace std;// 类模板
template
class demo
{
public:// 构造函数demo(){cout << "demo" << endl;}
};// 全特化
template<>
class demo
{
public:demo(){cout << "demo" << endl;}
};// 偏特化,对部分参数特化
template
class demo
{
public:demo(){cout << "demo" << endl;}
};// 偏特化,对满足条件的类型特化
// 当两个参数都是指针类型时的特化
template
struct demo
{
public:demo(){cout << "demo" << endl;}
};int main()
{// 调用模板,输出 demodemo d1;// 调用全特化,输出 demodemo d2;// 调用偏特化中的部分特化,输出 demodemod3;// 调用偏特化中的满足条件特化,输出 demodemod4;return 0;
}
通常在写项目时,都会将声明写在 .h 文件中,定义写在 .cpp 文件中,但是对于函数模板和类模板而言,如果将声明和定义分离,将会出现链接错误
// demo.h
#pragma once#include using namespace std;template
class demo
{
public:// 声明函数demo();
};// demo.cpp
#include "demo.h"// 定义函数
template
demo::demo()
{cout << "demo()" << endl;
}// test.cpp
#include "demo.h"int main()
{demo d;return 0;
}
编译时提示链接错误
// demo.cpp
#pragma once#include using namespace std;template
class demo
{
public:// 声明函数demo();
};// 定义函数
template
demo::demo()
{cout << "demo()" << endl;
}// test.cpp
#pragma once#include using namespace std;template
class demo
{
public:// 声明函数demo();
};int main()
{demo d;return 0;
}
编译完成后,由于 test.cpp 文件中有 demo 的声明,因此 demo
解决方法:
// 在 demo.cpp 文件中,像如下声明需要使用的类型
template
demo::demo();
// 只写 demo.h 文件,不需要 demo.cpp 文件
#pragma once#include using namespace std;template
class demo
{
public:// 声明函数demo();
};// 定义函数
template
demo::demo()
{cout << "demo()" << endl;
}
模板优点:模板增加了代码的复用性
模板缺点:模板出现编译错误时,错误信息非常凌乱,不容易查找到错误
上一篇:zigbee 外部中断
下一篇:Flink快速了解