C++超详细介绍模板

C++超详细介绍模板

1. 什么是模板

模板是一种通用的程序设计语言工具。它使程序员可以编写出适用于多种不同数据类型的函数或类。

在 C++ 中,模板可以定义函数模板和类模板。函数模板通常用于编写可以处理多种数据类型的函数,而类模板则用于创建可以适用于多种数据类型的类。

1.1 函数模板

函数模板可以定义一类函数,其中参数的类型和个数可以不确定。在定义函数模板时,需要使用 template 关键字,指定模板参数。例如:

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

上面的代码定义了一个 max 函数模板,其中输入参数为两个类型相同的值 ab,输出为两个值中的较大值。

使用函数模板时,需要在调用函数时指定模板参数。例如:

int main()
{
    int x = 3, y = 5;
    double a = 2.5, b = 1.6;

    std::cout << max<int>(x, y) << std::endl;
    std::cout << max<double>(a, b) << std::endl;

    return 0;
}

上面的代码分别输出了 xy 的最大值以及 ab 的最大值。

1.2 类模板

类模板可以定义一类类,其中数据类型可以不确定。在定义类模板时,需要使用 template 关键字,指定模板参数。例如:

template <typename T>
class Stack
{
public:
    Stack();
    void push(T value);
    T get();
    bool empty();
private:
    T* data;
    int count;
};

上面的代码定义了一个 Stack 类模板,其中数据类型为 TStack 类有两个公共函数 pushget,可以将数据压入栈中或弹出栈中的数据。

使用类模板时,需要在声明类时指定模板参数。例如:

int main()
{
    Stack<int> stack1;
    stack1.push(1);
    stack1.push(2);
    std::cout << stack1.get() << std::endl;

    Stack<char> stack2;
    stack2.push('a');
    stack2.push('b');
    std::cout << stack2.get() << std::endl;

    return 0;
}

上面的代码分别定义了两个不同的 Stack 类,其中一个将 int 类型数据压入栈中,一个将 char 类型数据压入栈中。

2. 模板详解

2.1 模板参数

模板参数分为两类:类型参数和非类型参数。

2.1.1 类型参数

类型参数可以是任何类型,但不包括函数类型和数组类型。类型参数可以使用 typenameclass 关键字进行声明。例如:

template <typename T>
void f(T x);

template <class T>
void g(T x);

上面的代码分别使用了 typenameclass 关键字声明了类型参数 T

2.1.2 非类型参数

非类型参数可以是任何常量表达式,包括整数、枚举、指针、成员指针等。在声明非类型参数时,需要使用 typenameclass 关键字。例如:

template <typename T, int N>
class Array
{
public:
    T data[N];
    int size() { return N; }
};

上面的代码定义了一个 Array 类模板,其中包含一个类型参数 T 和一个非类型参数 NArray 类模板用于创建一个可以容纳 N 个元素的数组。

2.2 模板类型推导

在调用函数模板时,可以忽略模板参数的指定,编译器会通过调用时传递的参数进行类型推导。例如:

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

int main()
{
    int x = 3, y = 5;
    double a = 2.5, b = 1.6;

    std::cout << max(x, y) << std::endl;
    std::cout << max(a, b) << std::endl;

    return 0;
}

上面的代码在调用 max 函数时没有指定模板参数,编译器通过调用时传递的参数推导出模板参数的类型。

2.3 模板特化

在某些情况下,需要为某些特定类型的数据提供特殊的处理方式。这时可以使用模板特化。

模板特化会在泛化模板的基础上提供一种或多种具体的实现。例如:

// 泛化模板
template <typename T>
void print(T a)
{
    std::cout << a << std::endl;
}

// 特化模板
template <>
void print<const char*>(const char* a)
{
    std::cout << "specialization: " << a << std::endl;
}

int main()
{
    print(123); // 调用泛化模板
    print("hello"); // 调用特化模板

    return 0;
}

上面的代码定义了一个 print 函数模板,其中泛化模板的参数类型为 T,特化模板的参数类型为 const char*。当传入 const char* 类型的参数时,会调用特化模板。

3. 示例

3.1 Stack 类模板示例

#include <iostream>

template <typename T>
class Stack
{
public:
    Stack() : data(new T[100]), count(0) {}
    void push(T value) { data[count++] = value; }
    T get() { return data[--count]; }
    bool empty() { return count == 0; }
private:
    T* data;
    int count;
};

int main()
{
    Stack<int> stack1;
    stack1.push(1);
    stack1.push(2);
    std::cout << stack1.get() << std::endl;

    Stack<char> stack2;
    stack2.push('a');
    stack2.push('b');
    std::cout << stack2.get() << std::endl;

    return 0;
}

上面的代码定义了一个 Stack 类模板,用于创建一个可以容纳任意数据类型的栈。在 main 函数中分别对 Stack<int>Stack<char> 进行了测试。

3.2 Vector 类模板示例

#include <iostream>
#include <vector>

template <typename T>
void printVector(std::vector<T>& vec)
{
    for (auto i = vec.begin(); i != vec.end(); ++i)
    {
        std::cout << *i << " ";
    }
    std::cout << std::endl;
}

int main()
{
    std::vector<int> vec1 = { 1, 2, 3 };
    std::vector<char> vec2 = { 'a', 'b', 'c' };
    printVector(vec1);
    printVector(vec2);
    return 0;
}

上面的代码定义了一个 printVector 函数模板,用于输出任意类型的 std::vector。在 main 函数中分别对 std::vector<int>std::vector<char> 进行了测试。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++超详细介绍模板 - Python技术站

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

相关文章

  • C语言实现文件读写

    文件读写是C语言的一个重要部分,文件读写操作主要是通过函数库提供的各种操作文件的函数来实现的。在实现文件读写时,主要分为以下几个步骤: 打开文件 C语言提供了fopen函数来打开文件,并返回一个指向文件的指针,该函数原型如下: FILE *fopen(const char *filename, const char *mode); 其中,filename表示…

    C 2023年5月23日
    00
  • C语言实现简易订餐系统

    C语言实现简易订餐系统 介绍 本文将详细讲解如何使用C语言实现简易订餐系统的完整攻略。这个简易订餐系统可以让用户选择菜单,订餐,结算和显示账单等功能。 步骤 步骤一:规划程序结构 在实现程序之前,我们可以先规划程序的整体架构,以此确定程序需要实现的功能和模块。我们大致可以将程序分成以下模块: 菜单模块:展示可选菜品列表。 点餐模块:让用户选择菜品和数量。 结…

    C 2023年5月23日
    00
  • C++实现简单信息管理系统

    下面是C++实现简单信息管理系统的完整攻略: 1. 确定需求 在开发信息管理系统之前,我们需要确定所需功能。例如,这个信息管理系统需要哪些模块、哪些操作、需要保存哪些信息等等。只有确定了这些需求之后,才能知道如何实现系统。 2. 设计系统框架 在确定了需求之后,可以开始设计系统框架。系统框架包括模块划分、数据结构设计等。可以使用流程图、UML图等工具来完成系…

    C 2023年5月23日
    00
  • C语言字符串声明

    C语言字符串可以理解为是由若干个字符(char)组成的数组,它以null字节为结尾。在C语言中,声明字符串变量需要特殊的语法,下面是一份讲解C语言字符串声明的完整使用攻略。 声明字符串变量 在C语言中,声明字符串变量需要使用char类型以及一对双引号(“”). 这里有几个重点需要注意: 字符串中的每一个字符都分配了存储空间。 字符串末尾会自动添加一个null…

    C 2023年5月9日
    00
  • Qt多线程实现网络发送文件功能

    下面是实现“Qt多线程实现网络发送文件功能”的完整攻略: 一、背景介绍 在网络编程中,有时需要向服务器发送文件,这时使用多线程能够提高发送效率和用户体验。Qt作为跨平台的C++框架,在多线程编程上提供了很好的支持,可以方便地实现多线程发送文件功能。 二、实现步骤 1. 创建子线程类 需要在主线程中创建子线程类,继承QThread类,并在其中重写其run()函…

    C 2023年5月22日
    00
  • log4j2 项目日志组件的实例代码

    以下是详细讲解“log4j2 项目日志组件的实例代码”的完整攻略。 什么是log4j2 log4j2是一个Java日志框架,可以提供高效灵活的日志记录服务,供各种Java应用程序使用。它是Apache软件基金会下的一个开源项目,其具备下列特点: 多种输出方式:文件、控制台、数据库等 丰富的API:易于使用、易于扩展 完善的日志级别:支持丰富的日志级别,能够控…

    C 2023年5月22日
    00
  • 如何解决Win10更新错误0x8024401c怎么办?Win10更新失败错误0x8024401c的解决方法

    针对Win10更新错误0x8024401c,以下是解决方法的完整攻略: 1. 检查网络连接 首先要检查网络连接是否正常,这是Win10更新失败的主要原因之一。可以尝试以下方法进行检查: 第一步:打开浏览器,打开任意网页,查看是否能正常访问; 第二步:确保网络连接正常,并尝试重新连接; 第三步:如果网络连接正常,尝试断开并重新连接网络,查看问题是否得到解决。 …

    C 2023年5月23日
    00
  • word安装mathtype以后出现无法复制粘贴怎么办?

    如果在安装Mathtype(数学公式编辑器)后,Word无法复制和粘贴的问题,可能是由于Mathtype默认设置更改了剪贴板的内容导致。以下是解决问题的完整攻略: 步骤一:打开Mathtype选项并调整设置 在Windows上,单击“开始”按钮并输入“Mathtype”以查找Mathtype应用程序。找到Mathtype并打开它。 点击“Mathtype”菜…

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