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++ 题解LeetCode1417重新格式化字符串

    C/C++ 题解 LeetCode 1417 重新格式化字符串 题目描述 给定一个由字母、数字和空格组成的字符串 s,你需要将其重新格式化,使得任意两个相邻字符之间都有且仅有一个空格,并且首尾字符之间也不能有空格。 返回 重新格式化后的字符串,如果无法按要求重新格式化,则返回一个 空字符串。 示例说明 示例 1 输入:s = “a0b1c2″输出:”a 0b…

    C 2023年5月24日
    00
  • 教你如何使用PHP输出中文JSON字符串

    下面是“教你如何使用PHP输出中文JSON字符串”的完整攻略: 1. 什么是JSON 在开始讲解如何使用PHP输出中文JSON字符串之前,我们需要先理解JSON是什么。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,大部分现代编程语言都支持解析和生成JSON数据。它基于JavaScript语言的子集,并且易于阅读和…

    C 2023年5月23日
    00
  • c语言实现的货物管理系统实例代码(增加删除 查找货物信息等功能)

    一、简介 货物管理系统可以帮助企业更好地管理其货品,是一套非常实用的管理系统。本文将介绍使用c语言实现的一套货物管理系统,包括增加、删除、查找货物信息等功能。 二、实现步骤 设计数据结构 首先,我们需要设计合适的数据结构用于存储货物信息。可以使用结构体来定义货物信息,例如: struct goods { int id; char name[50]; int …

    C 2023年5月23日
    00
  • 一篇文章带你了解C语言:入门基础

    一篇文章带你了解C语言:入门基础 什么是C语言? C语言是一门高级程序设计语言,它的发明者是丹尼斯·里奇和肯·汤普逊。C语言广泛应用于操作系统、编译器、网络设备、嵌入式系统、游戏开发等领域。学会C语言对程序员来说具有重要的意义。 C语言的编译和执行过程 C语言的编译和执行过程分为四个阶段,分别是预处理、编译、汇编和链接。 预处理 在预处理阶段,编译器会读取文…

    C 2023年5月23日
    00
  • 怎么在C++二进制文件中注入git信息详解

    下面是在C++二进制文件中注入git信息的完整攻略。 介绍 在C++开发中,我们经常需要借助版本控制工具Git来管理我们的项目代码,并且会在代码的开头注释中增加一些Git信息,如版本号、提交时间等。但是,这些Git信息只存在于代码中,如果我们需要将代码编译成二进制文件,如可执行文件或库文件,那么这些Git信息就无法被保留下来了。本教程将介绍如何在C++二进制…

    C 2023年5月23日
    00
  • C++获取多浏览器上网历史记录示例代码(支持获取IE/Chrome/FireFox)

    C++获取多浏览器上网历史记录示例代码攻略 在使用C++编程时,获取多浏览器上网历史记录是一项比较常用的操作,尤其是在开发一些浏览器小工具和浏览器扩展程序时。在这篇攻略中,我们将演示如何使用C++获取IE、Chrome和Firefox浏览器上网历史记录的示例代码,并且包含两个完整的示例说明。 支持的浏览器和实现方式 在编写代码之前,我们需要了解一下需要支持哪…

    C 2023年5月23日
    00
  • 在HTML5中使用MathML数学公式的简单讲解

    下面是HTML5中使用MathML数学公式的简单讲解: 什么是MathML MathML全称是Mathematical Markup Language,是用于在Web上显示数学公式的一种标记语言。MathML是XML的扩展,可以通过在HTML或XML文档中嵌入MathML代码来呈现数学公式。 如何使用MathML 需要指定DOCTYPE 为了使用MathML…

    C 2023年5月23日
    00
  • NBA2KOL安德森投篮包怎么样 C级球员投篮包介绍

    NBA2KOL安德森投篮包怎么样 C级球员投篮包介绍 简介 在NBA2KOL中,投篮包是非常重要的训练工具,它可以帮助球员提高投篮能力。其中,安德森投篮包被认为是一款比较实用的投篮训练工具,本文将详细介绍该投篮包的使用方法,并为大家介绍一些值得关注的C级球员投篮包。 安德森投篮包使用方法 打开NBA2KOL游戏,选择“训练”模式,在投篮训练界面中选择“安德森…

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