0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

现代C++之模板类型推导

汽车电子技术 来源:程序芯世界 作者:CoderWorld 2023-03-02 16:18 次阅读

1.传统C++ VS 现代C++

传统C++中,参数的类型都必须明确定义,这其实对我们快速进行编码没有任何帮助,尤其是当我们面对一大堆复杂的模板类型时,必须明确的指出变量的类型才能进行后续的编码,这不仅拖慢我们的开发效率,也让代码变得又臭又长。

C++11 引入了类型推导,让编译器来操心变量的类型。这使得 C++ 也具有了和其他现代编程语言一样,某种意义上提供了无需操心变量类型的使用习惯。

下面代码中CoderWorld(1,"Traditional","C++")是传统C++写法而CoderWorld(2,"Modern","C++")是现代C++写法,虽然使用了模板,但是其用法就像调用没有使用模板的普通函数一样,这样的代码明显更加具有易读性。这是因为C++11引入了类型推导,编译器会自动推导出参数的类型。

template

2.模板类型参数推导

模板类型参数推导共分为四种情况,下面会分别对这四种情况进行详细阐述。

  1. 函数形参的类型为指针或引用类型,但不是通用引用类型
  2. 函数形参的类型为通用引用类型
  3. 函数形参的类型既不是指针也不是引用
  4. 数组或函数名
模板类型推导案例1
template<typename T>
void CoderWorld(T& param);

int x = 27;
const int& rx = x;

CoderWorld(rx); // T is const int,  param's type is const int&

上述代码中函数CoderWorld(T& param)中形参的类型是引用类型(即T&), 推导遵循的规则如下:

在函数形参的类型为指针或引用类型,但不是通用引用类型情况下,需要去掉实参类型中的引用(这里的去掉引用是指去掉实参类型的引用,而不是形参param的类型T&中的&)。

对于CoderWorld(rx),实参rx为const int&类型,根据上述应该去掉实参rx 类型的引用,即将const int&中的&去掉,因此T被推导为const int 类型,最终param的类型T&为const int &类型。

模板类型推导案例2
template<typename T> void CoderWorld(T&& param);

int x = 27;
const int cx = x;
const int& rx = x;

CoderWorld(cx);//cx is lvale,so T is const int&,  param's type is const int&
CoderWorld(27);//27 is rvale,so T is int,param's type is int&&

上述代码中函数CoderWorld(T&& param) 形参类型是通用引用类型(即T&&),推导规则遵循如下:

在函数形参的类型为通用引用类型情况下,当实参的类型是左值时,param的类型和T的类型均为左值引用,当实参的类型是右值时,T的类型与实参一致,param的类型是实参类型的右值引用。

代码中cx是一个左值,因此T的类型与形参param的类型均推导为左值引用const int &。

当CoderWorld传入的参数是27时,因为27是右值,所以T的类型推导为int,param的类型推导为右值引用int&&

模板类型推导案例3
template<typename T> void CoderWorld(T param);

const int cx = x;
const int& rx = x;

CoderWorld(cx);//T and param are both int
CoderWorld(rx);// T and param are both int

上述代码中CoderWorld(T param)形参类型T即不是指针也不是引用类型,实际上是值传递,也就是说这种情况下形参param是实参的一个拷贝,推导规则遵循如下:

在函数形参的类型既不是指针也不是引用类型的情况下,如果实参的类型有引用,则忽略掉引用部分,如果实参类型有const,则忽略掉const部分,如果有volatile也忽略掉。

代码中实参cx的类型为const int,因此忽略掉const之后T的类型为int,形参param的类型也为int。

代码中实参rx的类型为const int &,去掉引用和const之后T的类型为int,形参param的类型也为int。

模板类型推导案例4

这是一种特殊的情况,就是当实参的类型是为数组和函数的时候需要注意。C++中,数组可以退化成指针,一个函数类型也是可以退化成指针的。具体的情况如下代码所示,结合注释记住这段代码中的CoderWorld1和CoderWorld2对数组和函数的推导情况即可。

template<typename T>
 void CoderWorld1(T param);
 template <typename T>
 void CoderWorld2(T& param);

 int arr = {0,1,2,3};
 void someFunc(int,double);

 CoderWorld1(arr);//arr会退化成指针,即param的类型为int*
 CoderWorld2(arr);//这里很有意思,param会被推导为 int (&)[4]
 //和上面的情况相比好处是param包含了数组的元素数量信息,可以获取到数组的成员数。
 CoderWorld1(someFunc);//param类型为函数指针 void (*)(int,double)
 CoderWorld2(someFunc);//param类型为函数引用 void (&)(int,double)

3.模板类型推导总结

参数类型 例子 推导规则
指针或引用类型,但不是通用引用类型 template void CoderWorld(T& param);void CoderWorld(T* param); 忽略实参引用
通用引用类型 templatevoid CoderWorld(T&& param); 实参为左值param为左值引用实参为右值param为右值引用
既不是指针也不是引用 templatevoid CoderWorld(T param); 忽略引用和const类型
数组或函数名 CoderWorld(arr)CoderWorld(someFunc) 数组退化为指针函数退化为函数指针image
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 参数
    +关注

    关注

    11

    文章

    1825

    浏览量

    32183
  • 编码
    +关注

    关注

    6

    文章

    940

    浏览量

    54807
  • C++
    C++
    +关注

    关注

    22

    文章

    2108

    浏览量

    73603
收藏 人收藏

    评论

    相关推荐

    关于C++模板总结

    大家好,今天给大家分享一篇关于 C++ 模板总结概述。
    发表于 09-19 11:55 514次阅读

    C++打印类型名称的分析与实现

    打印类型名称,听起来像是一个很简单的需求,但在目前的C++当中,并非易事。
    发表于 10-20 14:08 1393次阅读

    C++STL算法(二)

    C++STL算法(二)
    的头像 发表于 07-18 14:49 1027次阅读
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>STL算法(二)

    c++STL算法(三)

    c++STL算法(三)
    的头像 发表于 07-18 15:00 1269次阅读
    <b class='flag-5'>c++</b><b class='flag-5'>之</b>STL算法(三)

    C++文件操作

    C++文件操作
    的头像 发表于 07-21 10:52 1106次阅读
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>文件操作

    鸿蒙c++模板开发详解

    鸿蒙c++模板开发详解
    发表于 09-11 15:28

    C++课程资料详细资料合集包括了:面向对象程序设计与C++,算法,函数等

    本文档的主要内容详细介绍的是C++课程资料资料合集包括了:面向对象程序设计与C++,算法,函数,概述, C++语言基础,构造数据类型,数据类型
    发表于 07-09 08:00 18次下载
    <b class='flag-5'>C++</b>课程资料详细资料合集包括了:面向对象程序设计与<b class='flag-5'>C++</b>,算法,函数等

    数据结构的各种算法实现资料的C++模板概述

    本文档的主要内容详细介绍的是数据结构的各种算法实现资料的C++模板概述。
    发表于 12-20 16:35 6次下载

    C++函数模板的概念及意义

    一、函数模板的引出:1、c++中有几种交换变量的方法:(1)定义宏代码块(2)定义函数代码版本一:#include <iostream>#include <string>using namespace
    的头像 发表于 12-24 15:58 851次阅读

    c++ 布尔类型和引用的学习总结

    c语言里面我们知道是没有布尔数据类型的,而在C++中添加了布尔数据类型(bool),它的取值是:true或者false(也就是1或者0),在内存大小上它占用一个字节大小。
    的头像 发表于 12-24 18:03 591次阅读

    C++中为什么需要函数模板、类模板

    [导读] 最近使用C++做些编程,把日常遇到的些比较重要的概念总结分享一下。本文来分享一下模板类的原理,以及为什么需要模板类,使用时的基本要点。 为什么需要模板 比如需要设计一个描述点
    的头像 发表于 03-12 14:31 3133次阅读

    TouchGFX中Callback模板实现原理

    ,TouchGFX是用C++编写的,借助C++模板特性,定义了一组Callback模板,基于此模板来实现响应的功能。
    发表于 08-04 18:51 15次下载
    TouchGFX中Callback<b class='flag-5'>模板</b>实现原理

    C++学习笔记c++的基本认识

    自这篇文章我们即将开始C++的奇幻之旅,其内容主要是读C++ Primer的总结和笔记,有兴趣可以找原版书看看,对于学习C++还是有很大帮助的。这篇文章将从一个经典的程序开始介绍C++
    的头像 发表于 03-17 13:57 725次阅读

    C++入门string

    前一篇文章我们已经了解了C++中的基本类型C++还提供了很多抽象数据类型,例如字符串string,string包含多个字符,以及可变长度的vector,vector可以包含多个同一
    的头像 发表于 03-17 13:58 557次阅读

    C++之父新作带你勾勒现代C++地图

    为了帮助大家解决这些痛点问题,让大家领略现代C++美,掌握其中的精髓,更好地使用C++C++之父Bjarne Stroustrup坐不住
    的头像 发表于 10-30 16:35 832次阅读
    <b class='flag-5'>C++</b>之父新作带你勾勒<b class='flag-5'>现代</b><b class='flag-5'>C++</b>地图