1 模版结构体
模板结构体(Template Struct)是C++中使用模板定义的结构体类型。模板允许你编写通用的代码,使得结构体能够适用于多种数据类型。结构体(struct)与类(class)在C++中非常相似,主要区别在于默认的访问权限不同(结构体默认为公有,类默认为私有)。模板结构体的定义方式与模板类类似,主要通过template关键字后面跟着模板参数列表来实现。
- 基本语法
template <typename T>
struct StructName {
// 结构体的成员变量和成员函数定义
T var;
void func(T param) {
// 使用T类型的param执行某些操作
}
};
示例
下面是一个简单的模板结构体示例,定义了一个计算两个数之和的结构体:
template <typename T>
struct Adder {
T add(T a, T b) {
return a + b;
}
};
int main() {
// 实例化Adder结构体,用于处理int类型
Adder<int> intAdder;
std::cout << "Sum of 3 and 4 is: " << intAdder.add(3, 4) << std::endl;
// 实例化Adder结构体,用于处理double类型
Adder<double> doubleAdder;
std::cout << "Sum of 3.0 and 4.0 is: " << doubleAdder.add(3.0, 4.0) << std::endl;
return 0;
}
在这个例子中,Adder是一个模版结构体,它定义了一个名为add的成员函数,该函数接受两个相同类型的参数(由模版参数T指定),并返回它们的和。在main函数中,分别实例化处理了int和double类型的Adder,展示了模版结构体的泛型性。
2 模版特化
模板特化是C++模板编程中的一个高级特性,它允许程序员为特定的类型或特定的类型参数组合提供专门的实现。模板特化可以分为全特化和偏特化两种。该过程是静态的,在编译期完成。
- 全特化
全特化是指为模板的所有参数提供具体的类型。当使用这些特定类型实例化模板时,编译器将使用特化的版本而不是通用模板。
// 通用模板
template <typename T>
void swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
// 对于std::string的全特化
template <> //表示这是通用模版的特化版本
void swap<std::string>(std::string& a, std::string& b) {
// 使用std::string的成员函数swap,效率更高
a.swap(b);
}
在这个例子中,当调用swap函数且传入的参数为std::string类型时,编译器会使用特化的版本。直接利用std::string的成员函数swap进行交换,这通常比通过临时变量交换更高效。
3. 偏特化
偏特化允许我们只为模板的一个或多个参数提供特化,而其他参数保持通用。这是处理模板参数中部分类型需要特殊处理情况的有效方式。
// 通用模板类
template <typename T>
class Vector2D {
T x, y;
public:
Vector2D(T x_, T y_) : x(x_), y(y_) {}
// ... 其他成员函数
};
// 对T为int类型的偏特化
template <>
class Vector2D<int> {
int x, y;
// 由于int足够小,我们可以考虑内存对齐等优化
public:
Vector2D(int x_, int y_) : x(x_), y(y_) {}
// ... 可能的特定实现
};
- 两者对比
1 通用模版.
template<typename T1, typename T2>
struct Operation {
auto combine(const T1& a, const T2& b) -> decltype(a + b) {
return a + b;
}
};
->: 后置返回类型指定,与auto作用类似
decltype: 获取表达质类型
decltype(auto):保持初始化表达式的引用或非引用属性,同时自动推导类型
2 全特化
template<>
struct Operation<int, double> {
double combine(const int& a, const double& b) {
// 特殊化处理,例如转换整数为浮点数再相加
return static_cast<double>(a) + b;
}
};
3 偏特化
这个偏特化版本针对的是当T1和T2是同一类型的情况,此时combine函数执行的操作是相乘而不是相加。
template<typename T>
struct Operation<T, T> {
T combine(const T& a, const T& b) {
// 当两个类型相同时的特殊处理
return a * b;
}
};