一文详解C++模板和泛型编程

一文详解C++模板和泛型编程

简介

C++模板是实现泛型编程的基础。泛型编程是一种编程范式,通过参数化来实现算法的一种方式。C++模板可以用来定义不特定类型的函数、类等,可以减少代码的重复编写,提高代码的可维护性和可复用性。

模板的定义和使用

函数模板

函数模板可以用来定义可以适用于多种类型的函数。函数模板需要使用关键字template定义,后面跟尖括号<>中的类型参数。

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

上面定义了一个函数模板mySwap用于交换两个元素的值。T是类型参数,表示在调用函数的时候会具体化为某一种类型。函数模板调用时可以指定T的类型,也可以让编译器根据函数实参的类型自动推断出T的类型。

int a = 1, b = 2;
mySwap(a, b); // 实例化出 void mySwap<int>(int&, int&)

类模板

类模板可以用于定义适用于多种类型的类。类模板定义和函数模板定义相似,也需要使用template关键字来定义,尖括号中指定类型参数。

template<typename T>
class Stack {
    private:
        int top;
        T stack[100];
    public:
        Stack() : top(-1) {}
        void push(const T& item) {
            stack[++top] = item;
        }
        T pop() {
            return stack[top--];
        }
};

上面的代码定义了一个模板类Stack,可以适用于各种类型。T是类型参数,表示在使用时会被实际的类型替换。类模板中可以包含成员变量、成员函数等。使用类模板时需要指定类型参数,也可以让编译器根据类对象的成员类型自动推断出类型参数。

Stack<int> s;
s.push(1);
s.push(2);
int a = s.pop(); // a = 2

模板特化

模板特化是对通用模板进行特殊化处理,以便能够处理某些特定情况。模板特化可以分为两种,全特化和偏特化。

全特化

全特化是指将模板参数完全具体化,成为一个普通的函数或类定义。全特化时,需要在尖括号中指定具体的类型参数。

template<typename T>
class Compare {
    public:
        bool operator()(const T& a, const T& b) const {
            return a < b;
        }
};

template<>
class Compare<const char*> {
    public:
        bool operator()(const char* a, const char* b) const {
            return strcmp(a, b) < 0;
        }
};

上面的代码定义了模板类Compare,用于比较两个值的大小。当类型参数为const char*时,进行特化处理,特化版本提供了比较字符串的实现。

Compare<int> cmp;
bool res1 = cmp(1, 2); // true
Compare<const char*> s_cmp;
bool res2 = s_cmp("hello", "world"); // false

偏特化

偏特化是指将模板参数部分具体化,成为一个新的模板定义。偏特化时,需要在尖括号中指定一些或全部的类型参数。

template<typename T1, typename T2>
struct is_same {
    static const bool value = false;
};

template<typename T>
struct is_same<T, T> {
    static const bool value = true;
};

上面的代码定义了一个模板类is_same,用于比较两个类型是否相同。当类型参数相同时,进行偏特化处理,偏特化版本提供了true的值。

bool res1 = is_same<int, float>::value; // false
bool res2 = is_same<int, int>::value; // true

总结

  • C++模板是泛型编程的基础。
  • 函数模板和类模板可以适用于多种类型。
  • 使用类型参数和自动推断,可以使代码更加灵活、可维护、可复用。
  • 模板特化可以针对一些特定情况,提供更优的实现。
  • 全特化和偏特化是两种特化方式,可以针对具体情况进行处理。

以上是“一文详解C++模板和泛型编程”的完整攻略。接下来给出两个示例说明。

示例1:使用函数模板实现多种类型参数的加法

#include <iostream>
using namespace std;

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

int main() {
    int x = 1, y = 2;
    float a = 1.2, b = 3.4;

    cout << add(x, y) << endl;
    cout << add(a, b) << endl;
    return 0;
}

输出:

3
4.6

上面的代码中,使用了函数模板add,可以适用于intfloat两种类型,调用的时候会将类型参数实例化为具体类型。

示例2:使用类模板实现一个指针类型的栈容器

#include <iostream>
using namespace std;

template<typename T>
class Stack {
    private:
        int top;
        T* stack;
        int capacity;
    public:
        Stack(int size = 100) : top(-1), capacity(size) {
            stack = new T[size];
        }
        ~Stack() {
            delete[] stack;
        }
        void push(const T& item) {
            stack[++top] = item;
        }
        T pop() {
            return stack[top--];
        }
};

int main() {
    Stack<int*> s(3);
    int x = 1, y = 2, z = 3;
    s.push(&x);
    s.push(&y);
    s.push(&z);

    while(s.pop()) {
        cout << *s.pop() << endl;
    }

    return 0;
}

输出:

3
2
1

上面的代码定义了一个类模板Stack,用于存储指针类型。在主函数中,实例化了一个Stack<int*>对象s,并将几个指针推入栈中,最后弹出并输出所有指针所指向的值。

以上是两个示例,介绍了函数模板和类模板的使用。需要注意的是,在特化的时候,特化版本的实现需要和原模板的接口返回类型、参数列表都一致。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文详解C++模板和泛型编程 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 模拟鼠标事件的实现思路及代码

    实现模拟鼠标事件需要涉及到DOM操作、事件模型和浏览器兼容性问题等,下面是一个简单的实现思路和代码示例: 实现思路: 获取目标元素; 创建鼠标事件(如mousedown、mouseup、mouseover、mousemove等); 触发事件并将创建的事件对象作为参数传入; 处理事件回调函数中获取事件对象的信息。 代码示例1: HTML <div id=…

    C 2023年5月23日
    00
  • win10下VSCode+CMake+Clang+GCC环境搭建教程图解

    以下是“win10下VSCode+CMake+Clang+GCC环境搭建教程图解”的完整攻略。 简介 Visual Studio Code是一款非常流行的开源跨平台代码编辑器。而CMake、Clang和GCC则是C/C++开发中用到的重要工具和库,它们能够优化代码编译、调试等方面的问题。在win10系统下配置VS Code+CMake+Clang+GCC环境…

    C 2023年5月23日
    00
  • C语言入门篇–四大常量(字面,const修饰,宏,枚举)及标识符

    C语言入门篇–四大常量及标识符攻略 常量 字面常量 字面常量是指在程序中直接使用的常量,包括整型常量、实型常量、字符常量和字符串常量。 整型常量:在程序中直接写入的整数,如123,-456都是整型常量。 实型常量:包括浮点数和双精度浮点数,如3.14和5.76都是实型常量。 字符常量:单引号 ” 包裹的字符或转义字符的组合,如’A’、’?’或’\n’。 …

    C 2023年5月23日
    00
  • C#中的char、string和StringBuilder的使用详解

    C#中的char、string和StringBuilder的使用详解 在C#中,char、string和StringBuilder都是用来表示字符串以及相关操作的工具。本文将详细讲解它们的使用方法及不同点。 Char Char是一个表示单个Unicode字符的数据类型。在C#中,它通常用于对单个字符进行操作。以下是一些对Char变量进行操作的示例: char…

    C 2023年5月23日
    00
  • 移动m812c手机怎么样? 中国移动m812c参数配置详情介绍

    移动M812C手机怎么样? 移动M812C手机是中国移动推出的一款价格亲民的智能手机,旨在提供基本的移动通信和基础应用功能。下面将详细介绍它的参数配置和使用情况。 1. 参数配置 移动M812C手机参数如下: 屏幕:5.45 英寸屏幕,分辨率为 480 x 960 像素 处理器:联发科 MT6739WA 四核处理器 存储空间:2GB RAM + 16GB R…

    C 2023年5月23日
    00
  • C语言 保留字

    C语言保留字的使用攻略 在C语言中,保留字是指被C语言编译器预先定义并且有特定含义的关键字。C语言中共有32个关键字,这32个关键字在程序中不能被用作变量名或其他标识符名称。本文将详细介绍C语言中保留字的使用方法。 如何使用C语言的保留字 C语言中的保留字使用非常简单,只需要直接使用即可。以下是一些常见的保留字: auto break case char c…

    C 2023年5月9日
    00
  • C++实现小型图书管理系统

    C++实现小型图书管理系统攻略 1. 系统设计 图书管理系统主要包含以下功能:- 添加书籍- 删除书籍- 查询书籍信息- 修改书籍信息- 显示所有书籍 因此,我们可以设计一个Book类来表示一本书籍,其中包含以下属性:- 书名- 作者- 出版社- ISBN编号- 价格 下面是Book类的定义: class Book { public: string name…

    C 2023年5月23日
    00
  • C/C++编写推箱子小游戏

    C/C++编写推箱子小游戏攻略 推箱子是一款经典的益智游戏,C/C++语言是比较适合开发这类游戏的语言之一。下面我们将具体讲解如何用C/C++编写推箱子小游戏。 1. 游戏规则 玩家需要控制游戏主角——工人将箱子推到指定的位置,将所有箱子都推到规定位置即为过关。在游戏中,玩家需要通过方向键来控制工人移动,当工人移动到相邻的箱子处时,可以通过再次移动来推动箱子…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部