首页 > 编程语言 >C++模板初探究

C++模板初探究

时间:2024-07-25 16:56:05浏览次数:14  
标签:right 函数 int Add C++ 探究 模板 left

引言

        我们如果想要实现一个通用的交换函数,其中包含字符型,整型,双浮点型,该怎么办呢?我们当然可以选择使用函数重载,像这样:

void Swap(int& left, int& right)
{
    int temp = left;
    left = right;
    right = temp;
}

void Swap(double& left, double& right)
{
    double temp = left;
    left = right;
    right = temp;
}

void Swap(char& left, char& right)
{
    char temp = left;
    left = right;
    right = temp;
}

但是这样我们会发现会出现很多冗余的代码,我们能不能实现一个统一的函数来实现交换函数呢?

函数模板

概念

        函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

模板格式

template<typename T1, typename T2,......,typename Tn>

以上面的交换函数为例:

template<typename T>
void Swap( T& left, T& right)
{
    T temp = left;
    left = right;
    right = temp;
}

而值得注意的是:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)

原理

        函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器

模板的实例化

        模板的实例化就是模板的具体使用.

1. 隐式实例化

        让编译器根据实参推演模板参数的实际类型.即我们可以直接规定参数的类型,然后让编译器根据实参自己去推算出模板参数的实际类型,例如:

template<class T>
T Add(const T& left, const T& right)
{
    return left + right;
}

int main()
{
    int a1 = 10, a2 = 20;
    double d1 = 10.0, d2 = 20.0;
    Add(a1, a2);
    Add(d1, d2);

   此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
    Add(a, (int)d);
    return 0;
}
2.显示实例化

        在函数名后的<>中指定模板参数的实际类型. 如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错, 如下:

int main(void)
{
    int a = 10;
    double b = 20.0;

   显式实例化
    Add<int>(a, b);
    return 0;
}
3.模板参数的匹配原则

1.一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这
个非模板函数,下面以加法函数为例:

   专门处理int的加法函数
int Add(int left, int right)
{
    return left + right;
}

   通用加法函数
template<class T>
T Add(T left, T right)
{
    return left + right;
}

void Test()
{
    Add(1, 2);    与非模板函数匹配,编译器不需要特化
    Add<int>(1, 2);    调用编译器特化的Add版本
}

上面的代码Add后面不加类型的直接调用非模板函数,后面加类型的调用模板函数.

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而
不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模
板。

3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

类模板

与模板函数类似,类模板的定义格式为:

template<class T1, class T2, ..., class Tn>
class 类模板名
{
  类内成员定义
};
应用
// 类模版
template<typename T>
class Stack
{
public:
Stack(size_t capacity = 4)
{
    _array = new T[capacity];
    _capacity = capacity;
    _size = 0;
}

    void Push(const T& data);
private:
    T* _array;
    size_t _capacity;
    size_t _size;
};
类模板的实例化
Stack<int> st1; 
Stack<double> st2;

标签:right,函数,int,Add,C++,探究,模板,left
From: https://blog.csdn.net/Frenemy__/article/details/140676082

相关文章

  • Qt/C++使用小记1【.exe程序拖拽文件使程序启动时,获取该文件路径】
    写一写小小的收获吧,因为踏足也有一定时间了,自己也平时有记录,但是总感觉文件转来转去很麻烦,有时甚至找不到,就放在网上,自己需要的时候也可以翻一翻~第一个小收获:众所周知,qt生成的默认的.exe也是支持拖拽文件到.exe图标上的时候打开程序的,但是程序内不会有任何表现,仅仅是启动程......
  • Qt/C++使用小记7【qt单例模式-写日志/保存运行记录】
    小收获7众所周知,有时候需要记录行为操作,或者记录数据进行对比,甚至有的时候需要记录软件内的数据,来确认错误的地方或者验证数据的准确性,那么该如何进行呢这里我所使用的是使用“单例模式”来进行记录的,所以这个收获说是记录写日志,不如说是记录单例模式的使用~什么是单例模式?......
  • 程序设计:C++入门教程(速成) + 15道经典例题(附带例题解析)
    本文章以实用为主,若实在是不明白文字所表达的内容,无脑复制代码,自己动手运行一下,实验一下即可理解文章内容,放心,代码是全的,全选复制粘贴即可不废话,直接开整数据类型常用数据类型int:整数类型,用于表示整数值。例如:1,2,-3,0等。float:单精度浮点数类型,用于表示带有小数点的数......
  • C++中字符串的拼接和比较操作
    在C++中,字符串的拼接和比较是常见的操作,这些操作可以通过标准库中的std::string类来实现。下面将分别描述字符串的拼接和比较操作。字符串拼接在C++中,std::string类提供了多种方式来拼接(或称为连接)字符串。最直接的方法是使用+操作符或append()成员函数。使用+操作符cpp复......
  • C++中的四种类型转换(静态、动态、常量、重新解释。
    在C++中,类型转换是编程语言中的一个重要概念,它允许我们将一种数据类型的值转换为另一种数据类型。C++提供了四种主要的类型转换方式:静态类型转换(StaticCast)、动态类型转换(DynamicCast)、常量类型转换(ConstCast)和重新解释类型转换(ReinterpretCast)。每种转换都有其特定的用途......
  • C++(构造函数参数列表初始化)
    目录1.构造函数参数列表初始化的语法2.为什么使用参数列表初始化3.示例4.常量和引用成员的示例5.使用参数列表初始化的注意事项6.总结在C++中,构造函数参数列表初始化(initializerlist)是一种用于在对象创建时初始化成员变量的语法。这种方式在性能和可读性方面具有一些优势,......
  • HarmonyOS:组件Navigation使用中List显示不全的问题探究以及解决办法
    1.线性布局中在使用NavPathStack布局中中发现如果使用List组件会发现item显示不全,在使用官方提供的例子中也发现此问题。如图所示:底部被遮挡,官方示例的写法2.如果线性布局中,不显示导航栏,也会出现List被遮挡的问题如图所示:我们的页面布局中的List缺失一部分根据Previ......
  • C++数据和运算符
    回顾:XX.c  gcc专门编译C文件/g++XX.cpp g++专门编译C++文件.exe  执行.out#数据:数据类型****作用******对于计算机来说:编译器预算对象(变量)分配的内存空间大小对于用户来说:方便区分每种数据所代表的含义。什么类型参与运算最后结果还是什么类型基本类型......
  • C++深拷贝构造函数解决浅拷贝的堆区内存重复释放问题
    1.简单介绍先简单介绍一下浅拷贝和深拷贝:浅拷贝->简单的赋值拷贝操作,默认的拷贝构造函数就是浅拷贝。深拷贝->在堆区重新申请空间,进行拷贝操作。2.问题展示下面用代码示例明了地展示默认拷贝构造函数浅拷贝带来地堆区内存重复释放问题:#include<iostream>usingnamespace......
  • 片集 - 模板 - 1
    欢迎来看“片”(的简介)由于-\(看片\)-生涯转瞬即逝,于是我选择对“\(片\)”进行一定的总结:相信你一定看懂了由于开始的时间有一点晚,就姑且认为我以后会慢慢补充吧......线段树(区间加,区间求)点击查看代码#include<iostream>#defineendl'\n'#definelllonglongusing......