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() 这类数据绑定方法只能在数据绑定控件的上下文中使用" 的 ...
随机推荐
- html常用事件
1.onblur 当窗口失去焦点时运行 2.click 点击鼠标触发的事件 3.onfocus 当窗口获得焦点时运行 4.oninput 当元素获得用户输入时运行 5.onsubmit 当提交表单时运 ...
- AQS总结
前言 AQS(Abstract Queued Synchronizer)是JUC并发包中的核心基础组件,作者是大名鼎鼎的Doug Lea.通过AQS可以实现大部分的同步需求. 宏观架构 AQS包括一个 ...
- 基于SR-IOV的IO虚拟化技术
服务器配置要求 x86服务器内存不能低于32GB 服务器CPU需要支持虚拟化和设备虚拟化 VT-x VT-d,SR-IOV 功能,并且在BIOS中能启用了SR-IOV 网卡配置最起码为千兆配置 支持 ...
- 从Instagram“宁静、规则”的成功 看国内APP发展之路
看国内APP发展之路" title="从Instagram"宁静.规则"的成功 看国内APP发展之路"> Instagram在全球获得的巨大成功 ...
- React Docs(1)
安装 React在codepen上提供了一个Hello,World项目事例,只需打开网站,即可尝试React.另外还提供了一个html文件的Hello,World项目,项目中引用CDN的react.j ...
- 从未来看 C#
前言 如今 C# 虽然发展到了 8.0 版本,引入了诸多的函数式特性,但其实在 C# 未来的规划当中,还有很多足以大规模影响现有 C# 代码结构和组成的特性,本文中将会对就重要的特性进行介绍,并用代码 ...
- Python开发(二):列表、字典、元组与文件处理
Python开发(二):列表.字典.元组与文件处理 一:列表二:元组三:字典四:文件处理 一:列表 为什么需要列表 可以通过列表可以对数据实现最方便的存储.修改等操作.字符串是不能修改的,所以无法 ...
- Python基本小程序
目录 Python基本小程序 一.筛选从1-100所有的奇数 二.筛选从0-100所有的偶数 三.求1-100之间所有的偶数和,奇数和 四.三个数由小到大输出 五.四个数字重复数字的三位数 Pytho ...
- SQL Server 最小日志记录
SQL Server之所以记录事务日志,首要目的是为了把失败或取消的操作还原到最原始的状态,但是,并不是所有的操作都需要完全记录事务日志,比如,在一个空表上放置排他锁,把大量的数据插入到该空表中.即使 ...
- 【原创】为什么我的 Kafka 总是连接失败呢?
提出问题 近日助友 Docker 部署 Kafka 服务,服务日志启动正常,但客户端却无法连接 往日曾踩过此坑,然方法均源于博客,其语焉不详,不知为何不行,亦不知为何行,印象不甚深刻,耗费大量时间 为 ...