C++中的泛型:模板的作用与使用方法

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

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

开始课程

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



在编程世界中,经常需要编写能够同样良好地处理不同数据类型的代码。例如,数组排序函数应该能够排序整数、字符串或自定义对象。如果没有泛型编程(generics)机制,就必须为每种类型编写单独的函数,这会导致代码重复、错误和维护困难。



在C++中,这个问题通过模板(templates)解决——这是一个强大的工具,允许创建泛型函数和类。C++中的泛型概念正是通过模板实现的。它们允许程序员定义不依赖于特定类型的算法或数据结构,而是在编译阶段替换类型。



使用模板的主要优点:

  • 减少代码重复——一个模板可以替代多个重载函数。
  • 类型安全——所有类型检查都在编译阶段执行。
  • 性能——模板不会增加运行时开销,因为代码是为每个特定类型单独生成的。
  • 灵活性——可以创建复杂的泛型结构,包括容器(STL)和算法。


在本文中,我们将详细讲解如何在C++中使用模板,从简单示例开始,一直到高级技术。



函数模板基础



了解generics最简单的方法是编写一个模板函数。假设我们需要一个函数来查找两个值中的最大值。没有模板的话,必须为int、double、std::string等编写重载。使用模板只需一次完成:



#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 std::cout << max(3.14, 2.71) << std::endl; // double std::cout << max("apple", "orange") << std::endl; // const char* (字符串比较) return 0;}


这里关键字template声明模板,而typename T(或class T)指定类型参数。编译器会自动为每个使用的类型生成函数版本。重要的是,类型必须支持>运算符——否则会产生编译错误。



也可以指定多个类型参数:



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

// 使用printPair(42, "Hello"); // (42, Hello)


类模板:创建通用容器



类模板允许创建泛型数据结构——这是标准模板库(STL)的基础。考虑一个动态数组的模板类简单示例:



#include <iostream>#include <stdexcept>

template <typename T>class Array {private: T* data; size_t size;public: Array(size_t sz) : size(sz) { data = new T[size]; } ~Array() { delete[] data; } T& operator[](size_t index) { if (index >= size) { throw std::out_of_range("Index out of range"); } return data[index]; } size_t getSize() const { return size; }};

int main() { Array<int> intArray(5); // 整数数组 Array<double> doubleArray(3); // 浮点数数组

博客

书籍推荐