C++ 模版

一、类型参数模板

1. ​定义与用途
  • 作用:允许编写与类型无关的通用代码,支持泛型编程。
  • 语法:使用 template <typename T> 或 template <class T> 声明,T 为类型占位符。
  • 适用场景:函数或类需要处理多种数据类型时。
2. ​类模板示例
template <typename T>
class MyContainer {
private:
    T element;
public:
    MyContainer(T arg) : element(arg) {}
    T get() { return element; }
};

// 使用
MyContainer<int> intContainer(5);
MyContainer<double> doubleContainer(3.14);
3. ​函数模板示例
template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// 使用
int m = max(3, 5);        // 推导 T 为 int
double d = max(2.5, 3.0); // 推导 T 为 double
4. ​多参数与默认参数
template <typename T, typename U = int> // 默认参数 U=int
class Pair {
public:
    T first;
    U second;
    Pair(T f, U s) : first(f), second(s) {}
};

// 使用
Pair<double> p(3.14, 5); // U 默认为 int

二、非类型参数模板

1. ​定义与限制
  • 作用:模板参数为具体值(非类型),如整数、指针或引用。
  • 语法template <int N> 或 template <char* p>
  • 限制:参数必须是编译期常量(如整型、枚举、指针/引用)。
2. ​示例:固定大小数组类
template <int N>
class FixedArray {
private:
    int arr[N];
public:
    int& operator[](int index) { return arr[index]; }
};

// 使用
FixedArray<10> array; // 创建大小为 10 的数组
array[0] = 42;
3. ​指针/引用参数示例
template <const char* msg>
void printMessage() {
    std::cout << msg;
}

// 需要外部链接的常量
extern const char hello[] = "Hello";
printMessage<hello>(); // 输出 Hello

三、模板的特化

1. ​全特化(Explicit Specialization)​
  • 作用:为特定类型提供优化或特殊实现。
  • 语法template<> class ClassName<Type> { ... };
  • 示例
template <typename T>
class Printer {
public:
    void print(T val) { std::cout << val; }
};

// 全特化:针对 const char*
template <>
class Printer<const char*> {
public:
    void print(const char* val) { std::cout << "String: " << val; }
};

// 使用
Printer<int> p1; p1.print(5);       // 输出 5
Printer<const char*> p2; p2.print("Hi"); // 输出 String: Hi
2. ​偏特化(Partial Specialization)​
  • 作用:部分指定模板参数,处理某一类类型(如指针)。
  • 语法template <typename T> class ClassName<T*> { ... };
  • 示例
template <typename T>
class Comparator {
public:
    bool equal(T a, T b) { return a == b; }
};

// 偏特化:针对指针类型
template <typename T>
class Comparator<T*> {
public:
    bool equal(T* a, T* b) { return *a == *b; }
};

// 使用
Comparator<int> c1; 
bool b1 = c1.equal(5, 5); // true

int x = 5, y = 5;
Comparator<int*> c2;
bool b2 = c2.equal(&x, &y); // true

四、模板的分离编译

1. ​问题背景
  • 模板定义位置:模板的完整定义(包括成员函数)必须在使用前对编译器可见。
  • 传统分离编译:普通类可将声明放在 .h,定义放在 .cpp,但模板无法直接这样做。
2. ​示例:分离编译错误
// MyTemplate.h
template <typename T>
class MyTemplate {
public:
    void print(T val);
};

// MyTemplate.cpp
#include "MyTemplate.h"
template <typename T>
void MyTemplate<T>::print(T val) {
    std::cout << val;
}

// main.cpp
#include "MyTemplate.h"
int main() {
    MyTemplate<int> t;
    t.print(5); // 链接错误:找不到 print 的实现
}
3. ​解决方案
  • 头文件实现:将模板的声明和定义都放在 .h 文件中。
  • 显式实例化​(不推荐):在 .cpp 中显式实例化特定类型。
    // MyTemplate.cpp
    template class MyTemplate<int>; // 显式实例化 int 类型
    • 缺点:需提前知道所有可能使用的类型。

五、模板的优缺点总结

优点
  1. 代码复用:一份代码支持多种数据类型。
  2. 类型安全:编译时检查类型错误,避免运行时问题。
  3. 性能优势:编译时多态(如函数模板)无运行时开销。
  4. 泛型编程支持:实现通用算法(如 STL)。
缺点
  1. 编译时间增加:模板代码需多次实例化,编译速度慢。
  2. 代码膨胀:不同实例化版本生成多份机器码。
  3. 错误信息复杂:模板错误提示冗长难懂(如嵌套模板)。
  4. 跨平台问题:不同编译器对模板支持可能不一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值