【c++】模板进阶
如我们需要一个定长的数组时。控制数组长度的类型时确定的(如size_t),这样我们只设置一个类型参数就可以了。代码语言:javascriptAI代码解释注意:非类型模板参数只能用于整型;不支持浮点数,类对象和字符串。c++20之后可以支持double作非类型模板参数。非类型模板参数支持缺省值:代码语言:javascriptAI代码解释。
·
如我们需要一个定长的数组时。控制数组长度的类型时确定的(如size_t),这样我们只设置一个类型参数就可以了。
代码语言:javascript
AI代码解释
namespace xian
{
//定义一个模板类型的定长数组
template<typename T,size_t N>
class array
{
public:
T& operator[](size_t n)
{
return _array[n];
}
const T& operator[](size_t n) const
{
return _array[n];
}
size_t size()
{
return _size;
}
bool empty()
{
return 0 == _size;
}
private:
T _array[N];
size_t _size;
};
}
注意:非类型模板参数只能用于整型;不支持浮点数,类对象和字符串。c++20之后可以支持double作非类型模板参数。
非类型模板参数支持缺省值:
代码语言:javascript
AI代码解释
template<size_t N = 10>
class Stack
{
private:
int a[N];
int _top;
};
int main()
{
//Stack s0; 这种写法要c++20以后才支持
Stack<> s1; //我们还是用这种写法的好
}

模板的特化
函数模板的特化
代码语言:javascript
AI代码解释
// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
return left < right;
}
int main()
{
cout << Less(1, 2) << endl;
Date d2(2022, 7, 8);
Date d1(2022, 7, 7);
cout << Less(d1, d2) << endl;//可以正常判断
Date* p2 = &d2;
Date* p1 = &d1;
cout << Less(p1, p2) << endl; //会直接比较指针
return 0;
}

根据地址比较大小,而地址的申请时随机的,这样结果是不能确定的。对于这种有特殊情况的可以使用模板的特化,把特殊情况单独拿出来处理。
代码语言:javascript
AI代码解释
// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(Date* left, Date* right)
{
return *left < *right;
}
int main()
{
cout << Less(1, 2) << endl;
Date d2(2022, 7, 8);
Date d1(2022, 7, 7);
cout << Less(d1, d2) << endl;//可以正常判断
Date* p2 = &d2;
Date* p1 = &d1;
cout << Less(p1, p2) << endl; //会直接比较指针
return 0;
}
有特化后的类之后,会直接使用特化后的类。


总结:
- 主模板:定义通用的函数模板。
- 特化版本:为特定类型提供定制化实现。
- 调用:编译器根据参数类型自动选择主模板或特化版本。
- 注意事项:特化版本的函数签名必须与主模板一致,且不支持偏特化。
大多数时候,我们都选择简单的方法直接把特殊的情况函数直接给出而不是使用特化。使用特化容易出错,一般不要使用函数模板特化
更多推荐



所有评论(0)