C++ 函数模板与类模板

这篇具有很好参考价值的文章主要介绍了C++ 函数模板与类模板。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、函数模板

1、什么是函数模板?

现在的C++编译器实现了C++新增的一项特性–函数模板。函数模板是通用的函数描述,也就是说它们使用泛型来定义函数,其中的泛型可以是具体的类型(如int或double)。通过将类型作为参数传递给模板,可使编译器生成该类型的函数。用于模板允许以泛型的方式编写程序,因此,有时也称为通用编程。下面是一个函数模板的定义:

#include <iostream>
using namespace std;

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

int main(){
    int a = 10, b= 20;
    Swap(a, b);
    cout<<"a: "<<a<<endl;
    cout<<"b: "<<b<<endl;
    return 0;
}

2、重载函数模板

可以像重载常规函数定义那样重载函数模板定义,和常规重载一样,被重载的模板的函数特征标必须不同

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

template <typename Type>
void Swap(Type *a, Type *b, int n){
    Type temp;
    for(int i = 0; i < n; i ++){
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}

3、模板具体化

在代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。隐式实例化,显示实例化和显示具体化统称为具体化。例如:

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

3.1、隐式实例化

函数调用Swap(a, b)导致编译器生成Swap()的一个实例,该实例使用int型。模板并非函数定义,但是使用int的模板实例是函数定义,这种实例化方式成为隐式实例化。编译器之所以知道要进行函数定义,是由于程序调用Swap()函数时提供了int参数。例如:

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

template <typename Type>
void Swap(Type *a, Type *b, int n){
    Type temp;
    for(int i = 0; i < n; i ++){
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}

3.2、显式实例化

最初编译器只能通过隐式实例化,来使用模板生成函数定义。现在C++允许显示实例化,也就是说可以直接命令编译器创建特定的实例。其语法是,声明所需的种类–用<>符号指示类型,并在声明前面加上template,例如:

template void Swap<int>(int, int);

3.3、显示具体化

在程序中定义了下面的结构体,可以使用前面提供的Swap函数来交换两个结构体的内容。然而,假如只想交换name成员变量,而不交换age成员变量则需要使用不同的代码,但是Swap的参数将保持不变,因此无法使用模板重载来提供其他的代码。可以提供一个具体化函数定义–成为显示具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义而不再寻找模板。具体化机制随着C++的演变而不断发生变化,下面介绍C++标准定义的形式:

  • 对于给定的函数名,可以有非模板函数、模板函数与显示具体化模板函数以及它们的重载版本
  • 显示具体化的原型和定义应以template<>开头,并通过名称来指定类型
  • 具体化优先于常规模板,而非模板函数优于具体化与常规模板
#include <iostream>
using namespace std;

struct Student{
    string name;
    int age;
    Student(string name, int age):name(name),age(age){}
};

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

template <> void Swap<Student>(Student &a, Student &b){
    string name = a.name;
    a.name = b.name;
    b.name = name;
}

int main(){
    Student a("zhangsan", 20);
    Student b("lisi", 25);
    Swap(a, b);
    cout<<"a.name: "<<a.name<<endl;
    cout<<"b.name: "<<b.name<<endl;
    return 0;
}

二、类模板

2.1、什么是类模板?

继承与包含并不总是能解决重用代码的需要。例如,Stack类与Queue类都是容器类,容器类设计用来存储其他对象或数据类型。可以定义专门用于存储double值或string对象的Stack类,除了保存的对象类型不同外,这两种Stack类的代码是相同的。然而,与其编写新的类声明,不如编写一个泛型(即独立于类型的)栈。然后将具体的类型作为参数传递给这个栈,这样就可以使用通用的代码生成存储不同数据类型的栈。模板提供参数化类型,即能将类型名作为参数传递给接收方法来建立类或函数。

2.2、定义类模板

template <typename Type>
class Queue{
private:
    struct Node{
        Type item;
        struct Node *next;
    };
    Node *first;
    Node *rear;
    int queue_size;
public:
    Queue();
    ~Queue();
    bool isEmpty() const;
    bool push(const Type);
    bool pop();
    bool getFront(const Type &);
    int queueSize() const;
};

关键字template告诉编译器,将要定义一个模板,尖括号中的内容相当于函数的参数列表。上面声明的模板不是类与成员函数定义,它们是C++编译器指令,说明了如何生成类和成员函数定义。模板的具体实现(如用来处理string对象的栈类),被称为实例化或具体化。不能将模板成员函数放在独立的实现文件中。由于模板不是函数,它们不能单独编译,模板必须与特定的模板实例化请求一起使用。

2.3、使用类模板

仅在程序中包含模板并不能生成模板类,而必须请求实例化

Queue<int> qu1;
Queue<double> qu2;

看到上述声明之后,编译器将按Queue模板来生成两个独立的类声明和两组独立的类方法。
注意:必须显示的提供所需的类型,这与常规的函数模板是不同的,因为编译器可以根据函数的参数类型来确定要生成哪种函数

2.4、类模板具体化

类模板与函数模板很相似,可以有隐式实例化、显示实例化和显示具体化,它们统称为具体化文章来源地址https://www.toymoban.com/news/detail-418000.html

到了这里,关于C++ 函数模板与类模板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】:类和对象(下):explicit || 再谈构造函数 || static成员 || 友元 || 内部类 || 匿名对象 || 拷贝对象时的编译器优化问题 || 再次理解类和对象

    🔫类和对象(下篇) 🔫【本节目标】 🔫1. 再谈构造函数 🔫2. Static成员 🔫3. 友元 🔫4. 内部类 🔫5.匿名对象 🔫6.拷贝对象时的一些编译器优化 🔫7. 再次理解类和对象 🏄1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值

    2024年01月21日
    浏览(44)
  • 即时编译器的去虚化是什么?

    本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见100个问题搞定Java虚拟机 对于需要动态绑定的虚方法调用来说,即时编译器则需要先对虚方法调用进行去虚化(

    2024年02月01日
    浏览(38)
  • 初学Python,用什么编译器最好呢?

    新手学Python用什么编辑器比较好?工欲善其事必先利其器,选好工具学习更高效。市面上流行的编辑器众多,根据自己的需求选择适合自己。小白选择什么编译器比较好呢?今天主要介绍SublimeText、IDLE、VIM、PyCharm、Emacs编辑器,看它们都有什么功能,挑一个最适合小白学习的

    2024年02月09日
    浏览(48)
  • Visual C++ 使用x64编译器

    使用cmake编译mysql connector c++的时候,输出信息发现一个问题。 C:Program Files (x86)Microsoft Visual Studio2017ProfessionalVCToolsMSVC14.16.27023bin目录下居然有两个目录 Hostx86 Hostx64 这两个目录下都有x86和x64两个子目录。此时就糊涂了,为啥有Hostx64和Hostx86呢,还比较一下,发现这两个目

    2024年02月07日
    浏览(74)
  • 使用Microsoft C++编译器配置VSCode

    在本教程中,您将在 Windows 上使用 Microsoft Visual c++ 编译器和调试器配置 Visual Studio Code 。 要成功完成本教程,您必须完成以下步骤: 1.安装Visual Studio Code。 2.安装VS Code的C/ c++扩展。你可以通过在Extensions视图中搜索’c++’ (Ctrl+Shift+X) 来安装C/ c++扩展。 3.安装Microsoft Visual c++ (

    2024年02月05日
    浏览(53)
  • 免费的 C、C++ 编译器干活分享

    自由 Microsoft eMbedded Visual C++ : Microsoft eMbedded Visual C++允许您针对 Windows CE 进行开发。 它包括一个 IDE,其中包括一个集成的调试器。 免费微软 Visual C++ Toolkit 2003: Microsoft Visual C++ Toolkit 2003 包含命令行版本 的优化C++编译器、链接器和静态库(包括 商业视觉对象附带的标准

    2024年02月09日
    浏览(41)
  • C++ 函数模板与类模板

    现在的C++编译器实现了C++新增的一项特性–函数模板。函数模板是通用的函数描述,也就是说它们使用泛型来定义函数,其中的泛型可以是具体的类型(如int或double)。通过将类型作为参数传递给模板,可使编译器生成该类型的函数。用于模板允许以泛型的方式编写程序,因

    2023年04月19日
    浏览(47)
  • C++——函数模板与类模板

    C++知识合集 目录 1.泛型编程 2.函数模板 2.1函数模板实例化 2.2函数模板参数的匹配原则 3.类模板 4.模板的分离编译 实际上泛型编程的难度是比较高的,但我们泛型编程的初学者,当然要从简单的地方开始入手。 我们可以写出很多份交换函数,这些函数之间构成函数重载,这

    2024年02月08日
    浏览(44)
  • 即时编译器对于字段读取及存储指令的优化是什么?

    本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java虚拟机 即时编译器会优化实例字段以及静态字段访问,以减少总的内存访问数目。 具体来说,

    2023年04月08日
    浏览(73)
  • C++ | 探究拷贝对象时的一些编译器优化

    👑作者主页:@烽起黎明 🏠学习社区:烈火神盾 🔗专栏链接:C++ 在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的 经过深度探索类的六大天选之子学习,我们讲到了拷贝构造一些基本概念和调用形式 经过构造函数

    2023年04月19日
    浏览(85)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包