《C++》模板详解

一、模板定义及作用

  • C++模板是一种允许编写与数据类型无关的通用代码的编程机制,它通过在编译时进行代码生成来实现泛型编程。
  • C++模板的核心价值在于实现类型无关的通用代码,比如当你需要编写一个适用于任何数据类型的max()函数时,不必为intfloatstring等类型重复编写多份相同逻辑的代码,只需定义一个模板函数template <typename T> T max(T a, T b),编译器会自动为每种用到的类型生成特化版本,既避免了代码冗余,又保证了类型安全——就像用同一把模具(模板)铸造出不同材质的零件(具体实现),大幅提升了代码的复用性和可维护性

二、函数模板

2.1语法解释

  • 函数模板是C++中实现泛型编程的基础工具,它允许我们编写独立于具体类型的通用函数。
template <typename T>  // 或者 template <class T>
返回类型 函数名(参数列表) {
    // 函数体
}

示例:

template <typename T>
void Swap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

int main()
{
int a = 5, b = 10;
swap(a, b);  // 编译器生成swap<int>版本
    return 0;
}
  • 这里提一嘴,交换函数在C++可以直接使用,其名字为swap,故我们这里将其大写化避免重构。

2.2显示实例化

  • 显式实例化是C++模板编程中控制代码生成的重要机制,它允许开发者明确指定编译器在何时何地生成模板的特定类型实例。
  • 这常常用来处理数据类型冲突的时候。
// 函数模板显式实例化
template 返回类型 函数名<具体类型>(参数列表);

示例

template<class T>
T Add(const T& left, const T& right)
{
    return left + right;
}
int main(void)
{
    int a = 10;
    float b = 20.0;
    // 显式实例化
    int ret = Add<int>(a, b);//这里冲突了,那么就按int来进行处理
    cout << fixed << ret << endl;//输出30
    return 0;
}

2.3多个模板参数

  • 同样的,我们定义多个模板参数,示例如下:
template<class T1, class T2>
T2 Add(const T1& left, const T2& right)
{
    return left + right;
}
int main(void)
{
    int a = 10;
    float b = 20.0f;
    // 显式实例化
    float ret = Add(a, b);
    cout << fixed << ret << endl;//由于ret的类型是T2,T2匹配到的类型为float
    //故输出30.000000
    return 0;
}

2.4注意事项

  • 模板定义通常需要放在头文件中

  • 模板代码只有在被实例化时才会进行完整编译检查

  • 错误信息可能较为复杂难懂

  • 过度使用可能导致代码膨胀(编译生成多个实例)

三、类模板

3.1定义

  • 类模板是 C++ 中用于定义泛型类的机制,允许类成员(如数据成员、成员函数)使用参数化类型,从而让同一个类可以适用于不同的数据类型。
  • 其基本语法为:
template <typename T>  // 或 template <class T>
class ClassName {
public:
    T memberVar;  // 泛型成员变量

    ClassName(T val) : memberVar(val) {}  // 构造函数

    void print() {
        cout << memberVar << endl;
    }
};
  • template (或 template )声明这是一个类模板,T 是模板类型参数。

  • T 可以是任意类型。

3.2 类模板的实例化

  • 类模板本身并不是一个完整的类,必须显式或隐式实例化才能使用,而实例化的结果才是真正的类。。
  • 类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可。
int main() {
    // 显式实例化(指定 T 为 int)
    ClassName<int> obj1(10);
    obj1.print();  // 输出 10

    // 显式实例化(指定 T 为 string)
    ClassName<std::string> obj2("Hello");
    obj2.print();  // 输出 Hello

    return 0;
}

3.3类模板的默认模板参数

  • 类似的,我们依旧可以为类模板提供默认参数:
template <typename T = int>  // 默认 T 是 int
class Box {
public:
    T content;
    Box(T val) : content(val) {}
};

int main() {
    Box<> box1(10);  // 使用默认 int
    Box<std::string> box2("ABC");  // 显式指定 string
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值