C++ 中类模板参数的使用详解

发布于:2025-09-05 ⋅ 阅读:(20) ⋅ 点赞:(0)

1. 什么是类模板?

在 C++ 中,类模板(Class Template) 是一种定义类的通用方式,它允许我们在定义类时将类型(Type)或数值参数化,这样同一份代码可以适配不同的数据类型和常量值,从而提高代码的 复用性灵活性

类模板的定义语法一般为:

template <typename T>
class ClassName {
    // 类成员定义
};

其中,typename(或 class)引入了一个类型参数 T,在实例化时由用户指定具体的类型。


2. 类模板的参数类型

类模板参数主要分为三类:

2.1 类型参数(Type Parameter)

这是最常用的模板参数类型,用来在编译期间传入类型。

示例:

#include <iostream>
using namespace std;

template <typename T>
class MyContainer {
private:
    T data;
public:
    MyContainer(T value) : data(value) {}
    void show() { cout << data << endl; }
};

int main() {
    MyContainer<int> c1(42);       // 传入 int 类型
    MyContainer<string> c2("Hi");  // 传入 std::string 类型
    
    c1.show();  // 输出 42
    c2.show();  // 输出 Hi
}

说明:

  • T 是类型参数,在实例化类时会被替换成实际类型。
  • 实例化时 MyContainer<int>MyContainer<string> 是两个不同的类类型。

2.2 非类型参数(Non-type Parameter)

除了类型参数,模板也可以接受常量作为参数,比如整型、枚举、指针等(C++20 之后也可以用浮点数、字符串字面量)。

示例:

#include <iostream>
using namespace std;

template <typename T, int Size>
class Array {
private:
    T arr[Size];
public:
    void set(int index, T value) {
        if (index >= 0 && index < Size) {
            arr[index] = value;
        }
    }
    void display() {
        for (int i = 0; i < Size; ++i) {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    Array<int, 5> arr1;  // int 类型, 数组大小为 5
    arr1.set(0, 100);
    arr1.set(1, 200);
    arr1.display();  // 输出:100 200 0 0 0
}

说明:

  • 第二个模板参数 Size 是编译期常量(这里是 int),用来定义数组大小。
  • 非类型模板参数必须是编译期已知的常量。

2.3 模板模板参数(Template Template Parameter)

模板参数本身也可以是一个模板,比如容器类中使用的容器类型就可以作为参数。

示例:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

template <template <typename, typename> class Container, typename T>
class DataHolder {
private:
    Container<T, allocator<T>> data;
public:
    void add(const T& value) { data.push_back(value); }
    void show() {
        for (const auto& item : data)
            cout << item << " ";
        cout << endl;
    }
};

int main() {
    DataHolder<vector, int> vHolder;  // 使用 vector
    DataHolder<list, int> lHolder;    // 使用 list
    
    vHolder.add(1);
    vHolder.add(2);
    vHolder.show();  // 输出:1 2

    lHolder.add(3);
    lHolder.add(4);
    lHolder.show();  // 输出:3 4
}

说明:

  • 第一个模板参数 Container 本身是一个模板(如 std::vector)。
  • 必须完整写出 template <typename, typename> 来匹配容器的模板定义。

3. 类模板的默认参数

类模板的参数和函数一样,可以有默认值。

示例:

#include <iostream>
using namespace std;

template <typename T = int, int Size = 10>
class FixedArray {
private:
    T arr[Size];
public:
    void fill(const T& value) {
        for (int i = 0; i < Size; ++i)
            arr[i] = value;
    }
    void show() {
        for (int i = 0; i < Size; ++i)
            cout << arr[i] << " ";
        cout << endl;
    }
};

int main() {
    FixedArray<> a1;            // 使用默认 T=int, Size=10
    FixedArray<double, 5> a2;   // 自定义类型和大小
    
    a1.fill(7);
    a1.show();
    
    a2.fill(3.14);
    a2.show();
}

4. 部分特化(Partial Specialization)

有时我们希望针对某种特定的模板参数组合提供特殊实现,这时可以使用类模板特化。

示例:

#include <iostream>
using namespace std;

template <typename T, typename U>
class MyPair {
public:
    void show() {
        cout << "General template" << endl;
    }
};

// 针对第二个参数为 int 的特化
template <typename T>
class MyPair<T, int> {
public:
    void show() {
        cout << "Specialized for second parameter int" << endl;
    }
};

int main() {
    MyPair<double, char> p1;
    MyPair<float, int> p2;

    p1.show();  // General template
    p2.show();  // Specialized for second parameter int
}

5. 总结

类模板参数的灵活性让我们能够编写高度通用的类

  • 类型参数typename T)是最常用的,适用于泛型数据结构。
  • 非类型参数可以让结构在编译期固定某些常量,提升性能和安全性。
  • 模板模板参数适用于设计可接受不同容器或其他模板的泛型类。
  • 类模板也支持默认参数特化部分特化,让我们可以针对特定需求优化实现。

如果你希望在项目中写出高可复用性的代码,理解并灵活运用类模板参数将大有裨益。


网站公告

今日签到

点亮在社区的每一天
去签到