目录
1、函数模板
2、类模板
3、默认模板参数
4、非类型模板参数
5、模板的特化
1、函数模板特化
2、类模板特化
全特化
偏特化
6、模板别名
template
T max(T a, T b) {
return (a > b) ? a : b;
}
这里,template
定义了一个模板,其中 T
是一个类型参数。max
函数可以接受任意类型的参数,只要这两个参数的类型相同。
int m = Max
(3, 5); // 显式指定类型
double d = Max(3.2, 5.4); // 隐式推导类型
template
class Stack {
private:
std::vector elements;
public:
void push(T const& elem) {
elements.push_back(elem);
}
T pop() {
T elem = elements.back();
elements.pop_back();
return elem;
}
};
// 使用
Stack intStack;
Stack stringStack;
这里利用模板,创建了一个int类型的Stack对象和一个string类型的Stack对象。
你可以为模板提供默认的模板参数,这样在不提供实参时会使用默认值。例如:
template
T multiply(T a, T b) {
return a * b;
}
int main() {
cout << multiply(3, 4) << endl; // T被推导为int,因为int是默认类型
cout << multiply(3.5, 2.5) << endl; // T显式为double
}
在这个例子中,multiply(3, 4) 直接使用了默认的模板参数 T = int,而 multiply
模板参数分 类类型参数与非类型参数。
类类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
namespace zsxm
{
// 定义一个模板类型的静态数组
template
class array
{
public:
T& operator[](size_t index)
{
return _array[index];
}
private:
T _array[N];
size_t _size;
};
}
注意:
1、 浮点数、类对象以及字符串是不允许作为非类型模板参数的(只适用于整型)。
2、 非类型的模板参数必须在编译期就能确认结果。
通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理,下面举例说明:
特化:针对某些类型进行特殊化处理。
#include
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
bool operator<(const Date& d)
{
if ((_year > d._year)
|| (_year == d._year && _month > d._month)
|| (_year == d._year && _month == d._month && _day > d._day))
{
return false;
}
else
{
return true;
}
}
private:
int _year;
int _month;
int _day;
};
template
bool Less(T left, T right)
{
return left < right;
}
int main()
{
cout << Less(1, 2) << endl;
Date d1(2025, 3, 3);
Date d2(2025, 3, 2);
cout << Less(d1, d2) << endl;
Date* p1 = &d1;
Date* p2 = &d2;
cout << Less(p1, p2) << endl;
return 0;
}
为什么第三个会是1呢?因为p1的地址小于p2,但是我们想比较的是p1和p2指向的日期。所以我们需要进行模板特化,让它转化成对应的类型。
template<>
bool Less(Date* left, Date* right)
{
return *left < *right;
}
全特化是将模板参数列表中所有的参数都确定化。
template
class Data
{
public:
Data() {cout<<"Data" <
class Data
{
public:
Data() {cout<<"Data" < d1;
Data d2;
}
任何针对模版参数进一步进行条件限制设计的特化版本。
对于下面的类模板:
template
class Data
{
public:
Data() {cout<<"Data" <
部分特化
// 将第二个参数特化为int
template
class Data
{
public:
Data() {cout<<"Data" <
将参数特化为指针或者引用
//两个参数偏特化为指针类型
template
class Data
{
public:
Data() {cout<<"Data" <
class Data
{
public:
Data(const T1& d1, const T2& d2)
: _d1(d1)
, _d2(d2)
{
cout<<"Data" <
template
using Vec = std::vector;
// 使用
Vec v; // 等同于 std::vector