20.3 C++高级话题与新标准-理解函数模板类型推断与查看类型推断结果

文章介绍了如何查看C++函数模板的类型推断结果,强调了理解类型推断在现代C++开发中的重要性。通过使用Boost库来打印编译器推断的类型信息,作者提供了一种查看类型推断结果的方法,并给出了示例代码。接着,文章讨论了不同类型的形参(如指针、引用、万能引用、传值、数组和函数名)对类型推断的影响。
摘要由CSDN通过智能技术生成

3.理解函数模板类型推断与查看类型推断结果

类型推断(推导)这方面的相关知识在现代C++开发中是经常用到的,所以有必要对类型推断的知识理论做一些储备。本节主要讲解函数模板类型推断的知识。

  3.1 如何查看类型推断结果

从本节开始要讲述很多函数模板类型推断的相关知识,也会站在编译器的角度根据自己写的代码去模拟编译器来推断一些模板参数的类型和一些普通参数的类型。
那就存在一个问题,程序员自己推断出来的模板类型和普通参数类型与编译器推断出来的是否一样?自己推断出来的结论是否正确?
这就需要程序员能够知道编译器推断出来的模板参数类型和普通参数类型到底是什么!也就是说,现在要解决的问题是“如何查看类型推断结果”。程序员(读者)查看的当然是编译器给程序员进行类型推断的结果。
笔者的目的是希望读者通过“查看编译器类型推断结果”的手段来学习并掌握C++类型推断的规则,也就是说,最终要求读者掌握C++类型推断规则,而不是依赖什么手段去查看编译器给程序员推断出来的结果。
那如何查看编译器帮程序员进行类型推断的结果呢?方法不少,笔者也都进行了相关的资料查阅和研究,但是很多方法效果不好,输出的结果不准确。最终,笔者找到了一个比较靠谱的方法,该方法需要依赖Boost库。Boost库是存在多年很强大的一个库,可以把它当成C++标准库的延续和功能的扩充,它开源、跨平台,里面的代码也都是C++写的。如果有兴趣可以研究学习这个库。现在要解决的问题是:利用这个库来把编译器推断出的类型信息打印出来。这样操作:
(1)访问Boost官网https://www.boost.org/,网站中央有DOWNLOADS字样,其中包含最新版本的下载链接,如图20.1所示。单击其中的Version1.70.0(随着版本的升级,看到的版本号也许会更高)链接,进入专门的下载页面。
单击进入专门的下载页面后,如图20.2所示,把其中的Windows平台下的zip文件(boost_1_70_0.zip)下载下来(下载的文件大概有160MB)。
(2)将下载下来的zip文件解压到一个目录,如目录C:\Users\KuangXiang\Desktop\C++。
(3)回到Visual Studio开发环境中,在解决方案资源管理器中自己的项目名称上右击鼠标,在弹出的快捷菜单中选择“属性”(或者“项目”→“属性”)命令,在弹出的“MyProject属性页”对话框左侧选择“配置属性”→“VC++目录”,在右侧单击“包含目录”行,在该行右侧可编辑位置增加库路径(注意在增加库路径之前先增加一个分号做分隔)C:\Users\KuangXiang\Desktop\c++\boost_1_70_0,如图20.3所示。笔者用的是Visual Studio 2019,如果读者用其他版本的Visual Studio,可以通过搜索引擎寻找如何把Boost库相应的包含目录加入到项目中(方法和选项应该大同小异)。另外,不建议路径中包含中文、空格等特殊字符,以免出现意想不到的问题。
(4)回到MyProject.cpp文件中,在文件的前面位置包含如下头文件:
(5)具体“显示类型信息”相关的代码如下,可把这段固定的代码抄下来准备后续使用(可以把这段代码放在MyProject.cpp的前面位置)。

这里就不解释这些代码的工作原理,如果有兴趣可以自行研究。这些代码主要作用是显示模板参数T的类型信息和函数模板中参数tmprv的类型信息,显示的结果是人类可以读懂的字符串信息。
对整个项目进行编译,编译成功即可,这表示上面加入的这段Boost相关代码没有编译上的问题。

  3.2 理解函数模板类型推断

直接看代码,把刚才myfunc函数模板形参列表中的tmprv类型从T&修改为const T&,如下(函数体代码不变):
这里首先自己分析一下,感觉T应该会被推断为int类型,tmprv应该会被推断为constint&类型。注意,T是T,T是类型模板参数;tmprv是tmprv,tmprv是函数模板myfunc的形参,千万不要混为一谈。
执行起来,看一看结果:
根据结果显示不难看出,和上面自己推断的类型一样(结果中显示的tmprv=intconst&,其实和自己推断的constint &是同一个类型,只不过int和const顺序互换了一下)。
分析上例,表面看起来T的类型似乎来自于myfunc(100);代码行中的数字100,其实T的类型不仅和调用这个函数模板时给的实参(100)有关,还和整个这个tmprv的类型(constT&)有关。具体分析一下。

(1)指针或引用类型

如果tmprv类型是一个指针或者引用类型,但不是一个万能引用。
把刚才myfunc函数模板形参列表中的tmprv类型从constT&修改回T&,如下(函数体代码不变):

(2)万能引用类型

(3)传值方式

(4)数组作为实参

(5)函数名作为实参

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值