一、类型的萃取

在前面分析过类型的萃取,说的直白一些就是得到某些表达式或者变量的类型。这个如果在普通的编程里没啥难度,但在模板编程里或者一些特殊情况下就比较麻烦了,毕竟c++还是一门看上去高级其实仍然有些低级的语言(没有RTTI,Run-Time Type Identification)。这个结果就是c++没有办法从设计上得到运行期的类别类型。但是有困难压不领到英雄汉,在c++中还是有办法得到这些类型的,最典型的方法就是萃取。这个在前面介绍过,可以回头翻翻一下前面的公众号。
在c++中,其实有些情况下并不需要纯粹的获得这个类型的情况,比如CV限制等等可以不用考虑,那么在c++的库中,还是提供一些其它的获取类型的方式,下面介绍的std::decay就是如此,它定义在<type_traits>头文件中。

二、标准库中的std::decay

看一下定义:

template< class T >
struct decay;          (C++11 起)
对类型 T 应用左值到右值、数组到指针及函数到指针隐式转换,移除 cv 限定符,并定义结果类型为成员 typedef type 。正式而言:若 T 指名“ U 的数组”或“到 U 的数组的引用”类型,则成员 typedef type 为 U* 。
否则,若 T 为函数类型 F 或到它的引用,则成员 typedef type 为std::add_pointer<F>::type 。
否则,成员 typedef type 为 std::remove_cv<std::remove_reference<T>::type>::type 。
这些转换模仿在以值传递时,应用到所有函数参数的类型转换。
添加 decay 的特化的程序行为未定义。成员类型
名称  定义
type    应用退化类型转换到 T 的结果

其实这上面的说明就很好的解释了刚刚的情况,也就是说,这是可能会引起退化的操作,它会移除cv限定符并将数组退化为指针并消除引用(指针特性除外,如果想移除可使用std::remove_pointer)。type其实更详细的解释就是:T是引用类型,decay::type返回T引用的元素类型;当T是非引用类型,decay::type返回T的类型。

三、例程

看一下相关例程:

#include <iostream>
#include <type_traits>template <typename T, typename U>
struct decay_equiv : std::is_same<typename std::decay<T>::type, U>::type
{};int main()
{std::cout << std::boolalpha<< decay_equiv<int, int>::value << '\n'<< decay_equiv<int&, int>::value << '\n'<< decay_equiv<int&&, int>::value << '\n'<< decay_equiv<const int&, int>::value << '\n'<< decay_equiv<int[2], int*>::value << '\n'<< decay_equiv<int(int), int(*)(int)>::value << '\n';
}

这个程序的运行结果全是True。再回头对比一下相关的定义,就明白了。其实配合着上面提到的std::add_pointer和std::remove_pointer就可以实现把指针也退化掉的情况,根据工作中的实际应用来处理吧。其实这个东西单纯用在普通程序里意义不是多大。更多还是用在模板编程上。看下面的例子:

    template<typename T>static void MyFunc(Data& d, T&& s){using U = typename std::decay<T>::type;if (sizeof(U) <= size)new ((U*)&d) U(std::forward<U>(s));//new定位运算,即从指定的内存位置分配else*(U**)&d = new U(std::forward<U>(s));}

四、总结

不要小看每个小的细节的应用,这些应用一旦组合起来,可能产生一种无法想象的威力,这也是c++的魅力所在。如果在看一些开源框架中有些代码一看就头大时,不要害怕,把它拆开来分解学习,很快就明白他们的用处。如果无法全新的创新,那么组合的创新也不失为一种技术的进步。
打好基础,紧跟技术前进的脚步,这才是学好c++的前提。

跟我学c++中级篇——decay相关推荐

  1. 跟我学c++中级篇——类型擦除

    一.类型擦除 很多人一直都认为,类型擦除是一些高级语言(如Java)才具有的,其实在c++中也可以实现类型擦除.那么什么是类型擦除呢?我们都知道,C/c++是一门强类型语言,也就是说,编译器必须知道数 ...

  2. 跟我学c++中级篇——concepts的几个应用

    一.concepts的入门应用 concepts的应用是一个非常必要的问题.它对于模板在实际编程中的友好性有着至关重要的作用.先从最简单的一个示例说起: struct PlusSum{int d_ = ...

  3. 跟我学c++中级篇——STL字符串之std::string_view

    一.标准库字符串处理 C和C++的一个很不一样的区别就是对字符串的处理,在c++的标准库里提供了一个std::string的字符串操作类.这使得c++对字符串的操作从某种程度上摆脱了原始指针的操作.从 ...

  4. 『中级篇』docker导学(一)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』docker导学(一) 这两年容器技术及其相关工具,平台异常火爆.在各大技术论坛或云计算峰会议题中,都会占很大比重, ...

  5. 『中级篇』docker容器安装wordpress(37)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』docker容器安装wordpress(37) 第一节的时候我就部署过wordpress,可能很多老铁一头雾水不知道 ...

  6. Android中级篇之百度地图SDK v3.5.0-一步一步带你仿各大主流APP地图定位移动选址功能

    from: http://blog.csdn.net/y1scp/article/details/49095729 定位+移动选址 百学须先立志-学前须知: 我们经常在各大主流APP上要求被写上地址, ...

  7. Java工程师学习指南 中级篇

    Java工程师学习指南 中级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我写的文章都是站 ...

  8. 『中级篇』什么是Container(15)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』什么是Container(15) 镜像(Image),跟你装操作系统的iso镜像一个概念.容器(Container) ...

  9. 『中级篇』docker-swarm创建一个多节点集群(43)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』docker-swarm创建一个多节点集群(43) docker Swarm是Docker官方提供的一款集群管理工具 ...

  10. 运维“打怪”晋级之路之中级篇

    中级篇 有些人认为,其实运维就是部署某个软件,设置些基础功能,就算会运维了. 举个例子:安装LAMP,LNMP,就感觉部署方法我都掌握了.其实网上大多数都有一键安装脚本啥的根本没有啥技术含量,在面试官 ...

最新文章

  1. 深入Linux PAM体系结构
  2. Angular 项目 ng serve 背后发生的事情
  3. 【PhotoScan精品教程】任务一:新建工程、导入照片、设置坐标系、导入控制点(POS)、自由空三
  4. 实例12:python
  5. JDBC粗略学习( 阿巴阿巴阿巴阿巴)
  6. Linux启动报:UNEXPECTED INCONSISTENCY: RUN fsck MANUALLY问题解决
  7. Cron表达式 定时执行说明
  8. 两台服务器ubuntu20.x 直接文件共享,文件挂载 nfs
  9. 密码编码学与网络安全学习笔记
  10. vmware虚拟机安装win11系统教程
  11. ubuntu18之wine
  12. java入门12--面向对象(上)
  13. windows10搜索卡死(有出现Cortana的请看这篇文章)
  14. 使用ps命令结束相应进程
  15. Git在clone时认证失败后不能重新输入的解决方案
  16. 矩阵行列式引理 Matrix Determinant Lemma
  17. pdf中添加声音 java_PDF怎么添加音频?你不能错过的PDF编辑器办公软件
  18. 区块链 Hyperledger Composer 使用教程(环境搭建、项目开发 一)
  19. AP AUTOSAR 6——Execution Management
  20. Ubuntu系统中查看电脑驱动信息

热门文章

  1. 程序员写在猝死的前一天
  2. 唐青昊:Marvel Team 这一年 | 黑客 2016
  3. 哪些深度相机有python接口_三种主流深度相机介绍
  4. FLV视频合并-JAVA代码
  5. nofollow、noopener和noreferrer标签的区别
  6. Emacs快捷键 转自:http://www.engr.uvic.ca/~dastone/emacs-keys.html
  7. HDS NAS原理及Storage Pool方案
  8. Python中的Bunch模式
  9. 太空大战游戏开发实例
  10. 苹果手机怎么关闭自动调节亮度_怪不得手机总是耗电快,原来是这几个设置没关闭,看完涨知识了...