【C++】C/C++模板初阶(超详细解析,小白必看系列)

1 泛型编程

泛型编程(Generic Programming)是一种编程范式,旨在编写与具体数据类型无关的代码,从而实现代码的重用性和灵活性。在C++中,泛型编程的核心思想是通过模板(template)实现类型参数化,使得函数或类能够适用于多种数据类型

泛型编程的优点

  1. 代码重用性:无需为每种数据类型单独编写代码,大大减少了代码冗余。
  2. 类型安全:模板在编译时会进行类型检查,有效避免运行时错误
  3. 灵活性:可以处理不同类型的数据,而无需修改代码

示例

以下是一个简单的函数模板示例,它可以处理不同类型的数据:

#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << add(3, 4) << endl;        // 处理int类型
    cout << add(3.5, 4.5) << endl;    // 处理double类型
    return 0;
}

应用

泛型编程广泛应用于标准模板库(STL),如容器、迭代器和算法等。通过使用模板,STL能够提供高效且通用的解决方案

2. 函数模板

函数模板是C++中泛型编程的一个重要部分,它允许你编写独立于任何特定类型的函数。通过使用模板参数,你可以创建一个函数,该函数可以处理不同类型的数据。

2.1 函数模板的定义

函数模板的定义使用 template 关键字,后跟一个模板参数列表。模板参数列表中的每个参数都以 typenameclass 关键字开头。以下是一个简单的函数模板示例:

#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << add(3, 4) << endl;        // 处理int类型
    cout << add(3.5, 4.5) << endl;    // 处理double类型
    return 0;
}

在这个示例中,add 函数模板可以接受任意类型的参数,只要这些类型支持加法操作。

2.2 多个模板参数

你还可以定义带有多个模板参数的函数模板。例如,下面的示例展示了一个带有两个模板参数的函数模板:

#include <iostream>
using namespace std;

template <typename T1, typename T2>
auto multiply(T1 a, T2 b) -> decltype(a * b) {
    return a * b;
}

int main() {
    cout << multiply(3, 4.5) << endl;    // 处理int和double类型
    return 0;
}

在这个示例中,multiply 函数模板接受两个不同类型的参数,并返回它们的乘积。

2.3 模板实例化

C++中的模板实例化主要有两种方式:隐式实例化显式实例化

1. 隐式实例化

隐式实例化是编译器自动完成的。当你在代码中使用模板时,编译器会根据传递的模板参数自动生成相应的实例。例如:

#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << add(3, 4) << endl;        // 处理int类型,隐式实例化
    cout << add(3.5, 4.5) << endl;    // 处理double类型,隐式实例化
    return 0;
}

在这个例子中,add 函数模板会被隐式实例化为处理 intdouble 类型的两个不同版本。

2. 显式实例化

显式实例化是由程序员明确指定的。你可以在代码中显式地告诉编译器为特定类型生成模板实例。例如:

#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}


int main() {
    cout << add<int>(3, 4) << endl;        // 使用显式实例化的int版本
    cout << add<double>(3.5, 4.5) << endl;    // 使用显式实例化的double版本
    return 0;
}

3. 类模板

类模板是C++中泛型编程的一个重要部分,它允许你创建可以处理不同数据类型的类。通过使用模板参数,你可以编写一个类,该类可以适用于多种类型的数据。

3.1 类模板的定义

类模板的定义使用 template 关键字,后跟一个模板参数列表。模板参数列表中的每个参数都以 typenameclass 关键字开头。以下是一个简单的类模板示例:

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

template <class T>
class Stack {
private:
    vector<T> elems;  // 元素

public:
    void push(T const&);  // 入栈
    void pop();           // 出栈
    T top() const;        // 返回栈顶元素
    bool empty() const {  // 如果为空则返回真
        return elems.empty();
    }
};

template <class T>
void Stack<T>::push(T const& elem) {
    elems.push_back(elem);
}

template <class T>
void Stack<T>::pop() {
    if (elems.empty()) {
        throw out_of_range("Stack<>::pop(): empty stack");
    }
    elems.pop_back();
}

template <class T>
T Stack<T>::top() const {
    if (elems.empty()) {
        throw out_of_range("Stack<>::top(): empty stack");
    }
    return elems.back();
}

int main() {
    try {
        Stack<int> intStack;         // int 类型的栈
        Stack<string> stringStack;   // string 类型的栈

        intStack.push(7);
        cout << intStack.top() << endl;

        stringStack.push("hello");
        cout << stringStack.top() << endl;
        stringStack.pop();
        stringStack.pop();
    } catch (exception const& ex) {
        cerr << "Exception: " << ex.what() << endl;
        return -1;
    }
}

3.2 类模板的实例化

类模板的实例化与函数模板类似,可以通过显式实例化和隐式实例化来实现。例如:

Stack<int> intStack;       // 隐式实例化
Stack<string> stringStack; // 隐式实例化

3.3类模板的特化

类模板特化允许你为特定类型提供专门的实现。例如:

template <>
class Stack<bool> {
private:
    vector<int> elems;  // 使用int来存储bool值

public:
    void push(bool const& elem) {
        elems.push_back(elem ? 1 : 0);
    }
    void pop() {
        if (elems.empty()) {
            throw out_of_range("Stack<>::pop(): empty stack");
        }
        elems.pop_back();
    }
    bool top() const {
        if (elems.empty()) {
            throw out_of_range("Stack<>::top(): empty stack");
        }
        return elems.back() == 1;
    }
    bool empty() const {
        return elems.empty();
    }
};

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值