c++ 类模板与类成员函数模板(深入)
以下是关于C++类模板、类成员函数模板及类模板特化的全面说明,包含详细代码示例和场景分析:
一、类模板
1. 类模板定义
类模板允许开发者编写与类型无关的通用类结构,通过模板参数实现泛型编程。
语法
template <typename T1, typename T2, ...> // 模板参数列表
class ClassName {
// 类成员(数据和方法)的定义
};
示例
template <typename T>
class Vector {
private:
T* data;
size_t size;
public:
explicit Vector(size_t n) : size(n), data(new T[n]) {}
~Vector() { delete[] data; }
T& operator[](size_t index) { return data[index]; }
size_t getSize() const { return size; }
};
2. 实例化机制
(1) 显式实例化
定义:手动指定模板参数生成具体类。
语法:
template class ClassName<TypeArgs...>; // 显式实例化定义
extern template class ClassName<TypeArgs...>; // 显式实例化声明
使用场景:
- 减少编译时间(避免多文件重复实例化)
- 强制生成特定类型的模板实例
示例:
// 在.cpp文件中显式实例化定义
template class Vector<int>; // 显式实例化Vector<int>
template class Vector<double>; // 显式实例化Vector<double>
// 在.h文件中声明
extern template class Vector<int>; // 告诉编译器实例化在其他位置
(2) 隐式实例化
定义:编译器根据代码使用自动生成具体类。
示例:
Vector<std::string> strVec(5); // 隐式实例化Vector<std::string>
strVec[0] = "Hello"; // 隐式实例化operator[]
触发条件:当类模板被具体使用时(如创建对象、调用成员函数)。
3. 类模板使用场景
| 场景 | 示例 |
|---|---|
| 通用容器 | std::vector<T>, std::list<T> |
| 数学运算 | Matrix<T>, Complex<T> |
| 策略模式 | Sorter<T>, Serializer<T> |
| 元编程 | TypeTraits<T>, Tuple<T...> |
二、类成员函数模板
1. 普通类的成员函数模板
在非模板类中定义函数模板,允许成员函数支持多类型参数。
类内定义
class DataPrinter {
public:
template <typename T>
void print(const T& value) { // 成员函数模板
std::cout << "Value: " << value << std::endl;
}
};
// 使用
DataPrinter printer;
printer.print(42); // T=int
printer.print(3.14); // T=double
类外定义
class DataPrinter {
public:
template <typename T>
void print(const T& value);
};
template <typename T>
void DataPrinter::print(const T& value) {
std::cout << "Printed: " << value << std::endl;
}
2. 类模板的成员函数模板
在类模板中定义成员函数模板,实现更灵活的泛型操作。
(1) 类内定义
template <typename U>
class Wrapper {
U value;
public:
template <typename T> // 成员函数模板
void wrap(T&& val) {
value = std::forward<T>(val);
}
};
(2) 类外定义
template <typename U>
class Wrapper {
U value;
public:
template <typename T>
void wrap(T&& val);
};
template <typename U> // 类模板参数
template <typename T> // 成员函数模板参数
void Wrapper<U>::wrap(T&& val) {
value = std::forward<T>(val);
}
3. 实例化控制
(1) 隐式实例化
Wrapper<std::string> wrapper;
wrapper.wrap(42); // 实例化wrap<int>
wrapper.wrap("text"); // 实例化wrap<const char*>
(2) 显式实例化
// 显式实例化类模板
template class Wrapper<int>;
// 显式实例化成员函数模板
template void Wrapper<std::string>::wrap<double>(double&&);
三、类模板特化
1. 完全特化
为特定类型提供完全不同的实现。
示例
template <>
class Vector<bool> { // 针对bool的完全特化
private:
unsigned char* bitArray;
size_t size;
public:
explicit Vector(size_t n) : size(n), bitArray(new unsigned char[(n+7)/8]) {}
~Vector() { delete[] bitArray; }
bool operator[](size_t index) const {
return (bitArray[index/8] >> (index%8)) & 1;
}
};
使用:
Vector<bool> boolVec(10);
boolVec[3] = true; // 使用特化版本
2. 部分特化
为特定类型模式提供优化实现。
示例
// 通用模板
template <typename T>
class Comparator {
public:
static bool equal(const T& a, const T& b) {
return a == b;
}
};
// 针对指针类型的部分特化
template <typename T>
class Comparator<T*> {
public:
static bool equal(const T* a, const T* b) {
return *a == *b;
}
};
使用:
Comparator<int>::equal(5, 5); // 使用通用模板
Comparator<int*>::equal(&a, &b); // 使用指针特化
四、综合示例
1. 类模板+成员函数模板
template <typename T>
class DataProcessor {
T data;
public:
explicit DataProcessor(T val) : data(val) {}
template <typename U> // 成员函数模板
auto process(U modifier) -> decltype(data + modifier) {
return data + modifier;
}
};
// 显式实例化
template class DataProcessor<double>;
// 使用
DataProcessor<int> dp(10);
auto result = dp.process(3.14); // 隐式实例化process<double>
2. 特化应用场景
// 通用矩阵
template <typename T>
class Matrix { /* 通用实现 */ };
// 针对浮点数的优化特化
template <>
class Matrix<float> {
// 使用SIMD指令优化运算
};
// 使用
Matrix<int> intMat; // 通用实现
Matrix<float> floatMat;// 特化优化版本
五、关键注意事项
-
模板代码组织
- 类模板定义必须放在头文件中
- 显式实例化定义通常放在.cpp文件中
-
实例化规则
Vector<int> vec(5); // 隐式实例化类模板 vec[0] = 10; // 隐式实例化operator[] template class Vector<char>; // 显式实例化整个类 -
特化与重载的区分
template <typename T> void func(T val); // 主模板 template <> void func<int>(int val); // 特化 void func(int val); // 重载函数(非模板)
通过合理使用类模板及其特化机制,可以实现:
- 类型安全的泛型容器
- 高性能的数学库
- 灵活的策略模式实现
- 编译期多态
模板代码的调试复杂度较高,建议配合C++20的Concept特性进行类型约束。
636

被折叠的 条评论
为什么被折叠?



