C++ 泛型编程和模板
SFINAE
Substitution Failure Is Not An Error : 替换失败不是错误
*** 在模板的参数替换过程中,如果某个模板参数导致不合法的替换,编译器并不会立即报错,而是尝试寻找其他匹配的模板。 ***
当编译器在实例化一个模板时,进行模板参数替换,如果替换过程中发生了错误(例如类型不匹配、表达式非法等),编译器会忽略这个模板,而不会将其视为编译错误。
这时,编译器会继续寻找其他可能匹配的模板。如果没有找到其他匹配的模板,编译才会失败。
SFINAE 主要用于函数模板的重载,通过某些条件选择合适的模板函数,而忽略不适用的函数模板。
typename
template <typename T> |
typename 关键字的作用是在模板中显式声明一个依赖于模板参数的类型。在这里,std::enable_if<std::is_integral
是依赖于模板参数 T 的类型,因此需要使用 typename 来告诉编译器 type 是一个类型,而不是成员或其他符号。
模板
- 模板
- 模板全特化 : 全特化意味着你为某个具体类型完全重新定义模板的实现,而不是使用模板的默认实现。
using namespace std;
// 普通函数模板
template <typename T>
T add(T a, T b) {
return a + b;
}
// 函数模板的全特化:为 const char* 特化
template <>
const char* add(const char* a, const char* b) {
return "This is a specialized version for const char*";
} - 模板偏特化 : 在某些类型的基础上进行部分特化,而不是完全特化。它允许对部分模板参数进行特定类型的处理,而不需要完全指定所有参数的类型。
偏特化不能用于函数模板,只能用于类模板。偏特化常见的用法是在部分模板参数上进行特化处理。
using namespace std;
// 定义一个类模板,接受两个类型参数
template <typename T1, typename T2>
class MyClass {
public:
MyClass() {
cout << "Generic template version" << endl;
}
};
// 对类模板进行偏特化:当第二个类型参数为 int 时
template <typename T1>
class MyClass<T1, int> {
public:
MyClass() {
cout << "Partial specialization for T2 = int" << endl;
}
};
// 对指针类型进行偏特化
template <typename T>
class MyClass<T*> {
public:
MyClass() {
cout << "Partial specialization for pointers" << endl;
}
};
一个阶乘的简单例子
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 雷子集中营!