在函数模板中使用智能指针时,可能会希望根据指针的类型推导出指针引用的对象类型作为模板参数,于是写出以下代码:
shared_ptr<decltype(*objPtr)>(objPtr);
一眼看上去似乎是正确的,然而实际上隐藏着一个问题会导致错误,这要从decltype()推断出的类型说起。

decltype(a)推断出的类型

  • a为变量

    这是最简单的情况,推导出的类型为a的类型T
    int a = 0;
    decltype(a) b; //(int) b

  • a为右值表达式

    同上,推导出的类型为a的类型T
    decltype(2.f) b;   //(float) b
    decltype(b + 1) c;  //(float) c

  • a为左值表达式

    这时decltype推断出的类型是a的引用类型T&;,这也正是造成前文所述问题的根源。
    int b = 0;
    decltype(*(&b)) c; //error: declaration of reference variable 'c' requires an initializer

回到刚才说的shared_ptr的例子,假设objPtr的类型为Tdecltype(*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<>进行退化处理后再传入。

最新文章

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

热门文章

  1. 查漏补缺:进程间通信(IPC):管道
  2. sql问题处理
  3. hiho一下:Beautiful String
  4. Dubbo源码学习(二)
  5. first-child和first-of-type
  6. python爬虫-提取网页数据的三种武器
  7. alibaba开发手册
  8. 完整版EXCEL导出 (大框架SpringCloud 业务还是Springboot一套)
  9. XXE学习(一)——XML基础
  10. python之迭代器 生成器 枚举 常用内置函数 递归