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日

相关文章

  • Linux中文件系统truncate.c详解

    Linux中文件系统truncate.c详解 什么是truncate.c文件 truncate.c文件是Linux内核中负责处理文件截断操作的核心文件。其主要功能是截断指定文件的长度,可以对文件进行缩短或扩展。在Linux系统的文件系统中,文件截断操作是文件的常用操作之一。 truncate.c文件操作示例 1. 文件截断操作 truncate.c文件主要包…

    C 2023年5月24日
    00
  • Android json解析及简单例子

    好的。首先需要了解什么是JSON。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在不同的平台之间传输数据,常用于Web API的数据交换。在Android开发中,我们经常会用到JSON格式的数据,因此,掌握Android JSON解析技术是至关重要的。 JSON解析的基本方法 Android中常用的JSON解…

    C 2023年5月23日
    00
  • MathWorks Matlab R2020a(V9.8)密钥安装+永久激活详细教程(含下载)

    MathWorks Matlab R2020a(V9.8)密钥安装+永久激活详细教程(含下载) 一、下载Matlab R2020a Matlab官网提供了免费试用30天的版本,但如果需要永久性的使用,则需要购买正版。在下载前,请确保你购买了Matlab R2020a正版授权并获得了有效的密钥。 在Matlab官网中下载软件,下载链接为 https://www…

    C 2023年5月22日
    00
  • C语言中的pause()函数和alarm()函数以及sleep()函数

    C语言中时间相关函数详解 在C语言中,有许多与时间相关的函数,比如pause()、alarm()和sleep()。这些函数可以让我们在程序中实现不同的时间控制和延迟操作。下面,我们逐个来了解一下这些函数的具体用法。 pause()函数 pause()函数用于暂停当前进程的执行,直到收到一个信号为止。该函数的原型如下: #include <unistd.…

    C 2023年5月23日
    00
  • 基于Java实现Json文件转换为Excel文件

    基于Java实现Json文件转换为Excel文件的攻略: 引入相关依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.…

    C 2023年5月23日
    00
  • C++中四种对象生存期和作用域以及static的用法总结分析

    C++中四种对象生存期和作用域以及static的用法总结分析 在C++中,对象是程序中的基本组成单位之一。对象有不同的生存期和作用域,对于理解C++程序的运行过程至关重要。static是一个关键字,它有多种用途。本文将详细介绍C++中四种对象生存期和作用域以及static的用法。 对象的生存期和作用域 C++中的对象根据生存期和作用域的不同可以分为以下四类:…

    C 2023年5月22日
    00
  • C语言中强制类型转换的常见方法

    C语言中的强制类型转换指的是将一个数据类型转换成另一个数据类型。常见的强制类型转换方法包括以下几种: 1. 强制转换运算符 强制转换运算符包括(type)value、type(val)两种写法,其中type为要转换的目标数据类型,value为要转换的源数据。 示例: double a = 3.141592; int b = (int)a; // 强制将dou…

    C 2023年5月24日
    00
  • C程序 插入排序

    下面是关于”C程序 插入排序”的完整使用攻略。 插入排序是什么? 插入排序是一种简单直观的、比较常用的排序算法。其基本思想是将待排序的数组分成两部分,已排序和未排序,然后将未排序的元素一个一个插入到已排序部分的正确位置上,直到整个数组都被排序。 插入排序的实现 下面是一份C程序的插入排序实现,以进行升序排序为例。 #include <stdio.h&g…

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