C++中的泛型:模板,为什么需要以及如何使用

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:什么是C++中的泛型(模板)以及为什么需要它们?



在C++编程世界中,允许编写灵活、可重用且类型安全的代码的关键概念之一是模板。它们通常被类比为Java或C#等其他语言中的"泛型",尽管在C++中这个概念要强大和深刻得多。



想象一下你需要编写一个函数来查找数组中的最大元素。对于整数(int)需要一个函数,对于浮点数(double)需要另一个函数,对于字符串(std::string)还需要第三个函数。如果没有模板,你将不得不重复编写代码,这会导致错误并增加维护难度。



泛型(模板)解决了这个问题。它们允许你编写适用于任何数据类型的代码,而不会牺牲性能(与虚函数或void*不同)。模板是C++标准库(STL)的基础:容器(std::vector、std::map)、算法(std::sort、std::find)和智能指针(std::shared_ptr)——所有这些都是使用模板实现的。



在本文中,我们将详细分析C++中的模板是什么,如何正确声明和使用它们,并查看实际示例。



主要部分:如何在C++中使用泛型(模板)



1. 函数模板



开始使用泛型的最简单方法是创建一个函数模板。与其编写多个重载版本,不如编写一个以类型为参数的函数。



语法:

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


关键字template告诉编译器这是一个模板。<typename T>声明了类型参数T。你可以使用class代替typename——两者没有区别。



使用示例:

#include <iostream>#include <string>

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

int main() { std::cout << max(10, 20) << std::endl; // int: 20 std::cout << max(3.14, 2.71) << std::endl; // double: 3.14 std::cout << max(std::string("C++"), std::string("Python")) << std::endl; // string: Python return 0;}


重要提示:编译器会为使用的每种类型生成一个独立的函数版本。这被称为模板实例化。这样可以实现最大性能——没有虚函数调用的开销。



多个类型参数:

template <typename T1, typename T2>void printPair(T1 a, T2 b) {    std::cout << "(" << a << ", " << b << ")" << std::endl;}// printPair(1, "hello"); // 输出:(1, hello)


2. 类模板



类模板允许你创建通用的数据结构。一个经典的例子是std::vector<T>。你可以创建自己的模板类,例如一个简单的栈:



template <typename T>class Stack {private:    T* data;    size_t size;    size_t capacity;public:    Stack(size_t cap = 10) : size(0), capacity(cap) {        data = new T[capacity];    }    ~Stack() { delete[] data; }

void push(const T& value) { if (size < capacity) { data[size++] = value; } }

T pop() { if (size > 0) { return data[--size]; } throw std::out_of_range("Stack is empty"); }

bool isEmpty() const {

博客

书籍推荐