C++中decltype(*)作为模板实参时的隐藏问题
在函数模板中使用智能指针时,可能会希望根据指针的类型推导出指针引用的对象类型作为模板参数,于是写出以下代码: shared_ptr<decltype(*objPtr)>(objPtr);
一眼看上去似乎是正确的,然而实际上隐藏着一个问题会导致错误,这要从decltype()推断出的类型说起。
decltype(a)推断出的类型
a为变量这是最简单的情况,推导出的类型为
a的类型T。int a = 0;
decltype(a) b; //(int) ba为右值表达式同上,推导出的类型为
a的类型T。decltype(2.f) b; //(float) b
decltype(b + 1) c; //(float) ca为左值表达式这时
decltype推断出的类型是a的引用类型T&;,这也正是造成前文所述问题的根源。int b = 0;
decltype(*(&b)) c; //error: declaration of reference variable 'c' requires an initializer
回到刚才说的shared_ptr的例子,假设objPtr的类型为T,decltype(*objPtr)被推断为T&,但shared_ptr的模板实参应为T,所以产生了错误。想要解决这个问题,方法之一是使用std::decay<>
std::decay<>的使用
std::decay<>可以把类型的各种修饰(cosnt T, T&, etc.)退化,仅返回基本类型T(或T*,T*是不会被退化为T的)。
将std::decay应用于前文的代码,得到:
shared_ptr<typename std::decay<decltype(*objPtr)>::type>(objPtr);
注意typename关键字是不能省的,因为编译器无法区分std::decay<decltype(*objPtr)>的type成员到底是变量还是类型。
为了方便理解,本文以函数模板中shared_ptr的使用作为例子;但实际上这个问题可以推广到任何希望以decltype(*)作为模板实参时的场景:如果模板的实参并非T&,就必须通过std::decay<>进行退化处理后再传入。
C++中decltype(*)作为模板实参时的隐藏问题的更多相关文章
- 【C++ Primer 第16章】2. 模板实参推断
模板实参推断:对于函数模板,编译器利用调用中的函数实参来确定模板参数,从函数实参来确定模板参数的过程被称为模板实参推断. 类型转换与模板类型参数 与往常一样,顶层const无论在形参中还是在是实参中, ...
- Python中*args 和**kwargs作为形参和实参时的功能详解
*args 和**kwargs作为形参 *args 和**kwargs作为形参被称为不定长参数,用来处理超出必备参数部分的参数.注意:args和kwargs可以修改为其它变量名. 必备参数就是在定义函 ...
- C++中的函数模板
我们在定义函数时,可以通过定义函数模板,来简化一些功能相同而数据类型不同的函数的定义和调用过程. C++中的函数模板 对于类的声明来说,也有同样的问题.有时,有两个或多个类,其功能是相同的,仅仅是数据 ...
- C++ template —— 实例化和模板实参演绎(四)
本篇讲解实例化和模板实参演绎-------------------------------------------------------------------------------------- ...
- C++ Templates (1.4 默认模板实参 Default Template Arguments)
返回完整目录 目录 1.4 默认模板实参 Default Template Arguments 1.4 默认模板实参 Default Template Arguments 可以为模板参数定义默认值,这 ...
- C++ Templates (1.2 模板实参推断 Template Argument Deduction)
返回完整目录 目录 1.2 模板实参推断 Template Argument Deduction 1.2 模板实参推断 Template Argument Deduction 当调用函数模板(如max ...
- Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构
分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...
- Django中如何查找模板
参考:http://my.oschina.net/zuoan001/blog/188782 Django的setting中有关找模板的配置有如下两个: TEMPLATE_LOADERS TEMPLAT ...
- 如何解决FormView中实现DropDownList连动选择时出现 "Eval()、XPath() 和 Bind() 这类数据绑定方法只能在数据绑定控件的上下文中使用" 的错误
原文:如何解决FormView中实现DropDownList连动选择时出现 "Eval().XPath() 和 Bind() 这类数据绑定方法只能在数据绑定控件的上下文中使用" 的 ...
随机推荐
- javascript学习内容
http协议 犀牛书 MDN js单线程 let只在代码块内有效 es5只有全局作用域 const变量指向的内存地址不得改动,值不能保证不变 全局变量不加var node.js 更改连接到服务器的方式 ...
- iOS适配UIViewView/WKWebView,H5生成长图,仿微信进度条
前段时间撸代码猥琐发育的时候,设计师老王给了张截图某宝APP上一个生成长图分享的功能,正好公司有这个需求,于是在立马开始操练起来!在万能的度娘上搜集整理资料后发现很多文章介绍的方案对WKWebView ...
- OpenGL ES 学习笔记 - Overview - 小旋的博客
移动端图形标准中,目前 OpenGL ES 仍然是比较通用的标准(Vulkan 则是新一代),这里新开一个系列用于记录学习 OpenGL ES 的历程,以便查阅理解. OverView OpenGL ...
- 两种HTTP请求方法:GET和POST的区别
之前在一些开发者平台使用网页调用API时,一再提到两种请求方法GET和POST,所以就去了解了下.那么这又不得不提到HTTP了! 一.什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户 ...
- zookeeper 实战 - Pymjer 的博客
下载 $ wget http://apache.forsale.plus/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz 配置conf/zoo.cfg ...
- 天哪!毫无思绪!令人感到恐惧的数学(水题?)(TOWQs)
这道题的题目描述灰常简单,第一眼看以为是一道十分水的题目: 但是!!!(我仔细一看也没有发现这背后隐藏着可怕的真相~) 下面给出题目描述: 给出一个整数x,你可以对x进行两种操作.1.将x变成4x+3 ...
- VMware虚拟机各版本密钥
VMware Workstation Pro 激活许可证 UY758-0RXEQ-M81WP-8ZM7Z-Y3HDA VF750-4MX5Q-488DQ-9WZE9-ZY2D6 UU54R-FVD91 ...
- Sublime Text3 旧版本下载以及破解激活方式
前言 当前Sublime Text3 出到了32**版本,以前直接输入激活码的方法已经不能使用. 而官网又不提供旧版本的下载链接,因此在此分享旧版本下载方式以及激活方式. 下载方法 通过下面这个链接下 ...
- Hibernate入门之注解@Column详解
前言 上一节我们讲解了Hibernate的主键生成策略,本节我们继续来讲讲Hibernate中针对列的映射即@Column注解,文中若有错误之处,还望指正. @Column注解详解 我们看到如上针对列 ...
- JZOJ 5328. 【NOIP2017提高A组模拟8.22】世界线
5328. [NOIP2017提高A组模拟8.22]世界线 (File IO): input:worldline.in output:worldline.out Time Limits: 1500 m ...