【C++】:模板初阶—函数模板 | 类模板

在C++中,模板是一种强大的泛型编程工具,它允许我们编写可以处理不同类型数据的函数或类,而无需为每种数据类型重复编写代码。模板分为函数模板类模板,它们通过参数化的方式,使得代码具有更好的通用性和复用性。

一、函数模板

函数模板允许函数的参数类型是泛型的,即在函数定义时,参数的类型并不确定,只有在调用函数时才确定具体的类型。

1. 函数模板的基本定义

模板函数通常使用template关键字来定义,后面紧跟模板参数声明,使用时由编译器推导参数类型。

#include <iostream>

// 定义一个模板函数,用于返回两个值中的较大者
template <typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    int a = 10, b = 20;
    double c = 5.6, d = 3.2;

    std::cout << "较大的整数是: " << getMax(a, b) << std::endl; // 自动推导为 int
    std::cout << "较大的浮点数是: " << getMax(c, d) << std::endl; // 自动推导为 double

    return 0;
}

输出结果:

较大的整数是: 20
较大的浮点数是: 5.6
2. 显式指定模板参数

虽然通常情况下,编译器可以根据实参自动推导模板参数类型,但在某些情况下,你可以显式指定模板参数类型。

#include <iostream>

template <typename T>
T getMin(T a, T b) {
    return (a < b) ? a : b;
}

int main() {
    int x = 100, y = 200;
    double p = 10.5, q = 20.5;

    // 显式指定模板参数为 int 类型
    std::cout << "较小的值 (int): " << getMin<int>(x, y) << std::endl;

    // 显式指定模板参数为 double 类型
    std::cout << "较小的值 (double): " << getMin<double>(p, q) << std::endl;

    return 0;
}

输出结果:

较小的值 (int): 100
较小的值 (double): 10.5
3. 模板的重载与特化

模板函数可以像普通函数一样被重载,同时也可以通过特化来为特定类型提供定制化的实现。

(1) 重载模板
#include <iostream>

template <typename T>
T getAbs(T a) {
    return (a < 0) ? -a : a;
}

// 重载:专门处理浮点类型
double getAbs(double a) {
    std::cout << "处理浮点类型" << std::endl;
    return (a < 0) ? -a : a;
}

int main() {
    int i = -10;
    double d = -5.6;

    std::cout << "整数绝对值: " << getAbs(i) << std::endl;
    std::cout << "浮点数绝对值: " << getAbs(d) << std::endl;

    return 0;
}

输出结果:

整数绝对值: 10
处理浮点类型
浮点数绝对值: 5.6
(2) 模板特化

有时我们希望为某个特定类型提供不同的实现,这时可以使用模板特化。

#include <iostream>

// 通用版本的模板
template <typename T>
T getAbs(T a) {
    return (a < 0) ? -a : a;
}

// 针对 char 类型的特化版本
template <>
char getAbs(char a) {
    std::cout << "字符绝对值并不适用" << std::endl;
    return a;
}

int main() {
    int i = -10;
    char ch = 'A';

    std::cout << "整数绝对值: " << getAbs(i) << std::endl;
    std::cout << "字符绝对值: " << getAbs(ch) << std::endl;

    return 0;
}

输出结果:

整数绝对值: 10
字符绝对值并不适用
字符绝对值: A

二、类模板

类模板类似于函数模板,它允许我们创建泛型类。在类模板中,我们可以定义成员函数和成员变量的类型是模板参数。

1. 类模板的基本定义

类模板同样使用template关键字来定义,模板参数可以应用于类的成员函数、成员变量等。

#include <iostream>

// 定义一个通用的 Pair 类模板,用于存储两个不同类型的值
template <typename T1, typename T2>
class Pair {
private:
    T1 first;
    T2 second;

public:
    Pair(T1 a, T2 b) : first(a), second(b) {}

    void display() const {
        std::cout << "First: " << first << ", Second: " << second << std::endl;
    }
};

int main() {
    Pair<int, double> p1(10, 3.14);
    Pair<std::string, char> p2("Hello", 'A');

    p1.display();
    p2.display();

    return 0;
}

输出结果:

First: 10, Second: 3.14
First: Hello, Second: A
2. 类模板的成员函数定义

类模板的成员函数可以直接在类内定义,也可以像普通类一样在类外定义。

#include <iostream>

template <typename T1, typename T2>
class Pair {
private:
    T1 first;
    T2 second;

public:
    // 构造函数
    Pair(T1 a, T2 b) : first(a), second(b) {}

    // 成员函数在类外定义
    void display() const;
};

// 类外定义成员函数
template <typename T1, typename T2>
void Pair<T1, T2>::display() const {
    std::cout << "First: " << first << ", Second: " << second << std::endl;
}

int main() {
    Pair<int, double> p(42, 6.28);
    p.display();

    return 0;
}

输出结果:

First: 42, Second: 6.28
3. 类模板的继承

类模板可以继承另一个类模板或普通类,甚至可以实现多重继承。

#include <iostream>

// 基类模板
template <typename T>
class Base {
protected:
    T value;

public:
    Base(T v) : value(v) {}

    void display() const {
        std::cout << "Base value: " << value << std::endl;
    }
};

// 派生类模板
template <typename T>
class Derived : public Base<T> {
public:
    Derived(T v) : Base<T>(v) {}

    void show() const {
        std::cout << "Derived value: " << this->value << std::endl;
    }
};

int main() {
    Derived<int> obj(100);
    obj.display();  // 调用基类方法
    obj.show();     // 调用派生类方法

    return 0;
}

输出结果:

Base value: 100
Derived value: 100

三、模板的使用场景

模板广泛用于C++标准库和第三方库中,尤其是在容器算法智能指针等泛型编程中。C++ STL(标准模板库)中,容器如vectorlistmap等,都是基于模板实现的。

1. 标准模板库(STL)中的模板

例如,std::vector是C++标准库中的动态数组,它是一个类模板,可以存储任意类型的元素。

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    for (int v : vec) {
        std::cout << v << " ";
    }

    std::cout << std::endl;
    return 0;
}

输出结果:

1 2 3 4 5

四、总结

C++模板是泛型编程的核心工具之一,通过函数模板和类模板,我们可以编写通用性极强的代码,大大减少重复代码的编写。函数模板使函数可以接受不同类型的参数,而类模板则允许类对不同数据类型进行操作。模板是现代C++编程不可或缺的一部分,掌握模板将大大提升代码的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只蜗牛儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值