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<>
进行退化处理后再传入。
最新文章
- unable to boot the simulator,无法启动模拟器已解决
- java和android的环境变量配置
- jsoup简单的爬取网页数据
- Oracle警告、跟踪文件(10046、死锁等跟踪)
- CXF+Spring 搭建的WebService
- CSS 负边距自适应布局
- jquery.lazyload的使用
- [LeetCode] Magical String 神奇字符串
- 大白话Vue源码系列(05):运行时鸟瞰图
- day20-多并发编程基础(一)
- Day047--JS BOM介绍, jQuery介绍和使用
- vscode配置git及码云
- XAML: 在 MVVM 模式中,关于绑定的几处技巧
- GitLab篇之Linux下环境搭建
- Xmind 8 pro 软件破解版
- centos7 + mysql5.7 tar包解压安装
- 【PyQt5 学习记录】009:批量创建组件并查找
- javascript 分号理解
- Oracle DB 数据库维护
- NOI Linux学习