c++11 std::decay源码剖析

写在最前。。。

 

请支持原创~~ 

 

 

0. 前言

《c++11 std::is_same》https://justinwei.blog.csdn.net/article/details/120268292https://justinwei.blog.csdn.net/article/details/120268292中提到is_same 是严格的类型比对,包含了CV 属性的对比,例如 int 和const int 在is_same 中不是一个类型,返回值也是为false。但是有些时候我们想要排除CV属性进行浅层次比对,怎么办?本文的decay 可以做到!

1. 头文件

#include <type_traits>

2. 声明

template <class T> struct decay; //c++11

template <class T>using decay_t = typename decay<T>::type;  // C++14

decay 是在c++11 发布的,在c++14中发布了decay_t 用以标记decay 的type。

3. 实现

实现大致如下,下面是代码整合后的结果,实际在type_traits 中,成员变量type 是在 struct __decay 中定义的。

template< class T >
struct decay {
private:
    typedef typename std::remove_reference<T>::type U;
public:
    typedef typename std::conditional< 
        std::is_array<U>::value,
        typename std::remove_extent<U>::type*,
        typename std::conditional< 
            std::is_function<U>::value,
            typename std::add_pointer<U>::type,
            typename std::remove_cv<U>::type
        >::type
    >::type type;
};

为类型T应用从左值到右值(lvalue-to-rvalue)数组到指针(array-to-pointer)函数到指针(function-to-pointer)的隐式转换。转换将移除类型T的cv限定符(const和volatile限定符),并定义结果类型为成员decay<T>::type的类型。这种转换很类似于当函数的所有参数按值传递时发生转换。

  • 如果类型T是一个函数类型,那么从函数到指针的类型转换将被应用,并且T的衰变类型等同于:add_pointer<T>::type
  • 如果类型T是一个数组类型,那么从数组到指针的类型转换将被应用,并且T的衰变类型等同于:add_pointer<remove_extent<remove_reference<T>::type>::type>::type
  • 当左值到右值转换被应用时,T的衰变类型等同于:remove_cv<remove_reference<T>::type>::type

这里涉及到remove_reference,这也是type_traits 中的类型,通过名称就可以看出来,主要根据T 取出& 或 && 得到最后的type,去除引用的属性:

template <class _Tp> struct  remove_reference        {typedef _Tp type;};
template <class _Tp> struct  remove_reference<_Tp&>  {typedef _Tp type;};
template <class _Tp> struct  remove_reference<_Tp&&> {typedef _Tp type;};

同理,remove_cv 也是将const 和volatile 的属性用typedef 的方式去掉:

template <class _Tp> struct  remove_volatile               {typedef _Tp type;};
template <class _Tp> struct  remove_volatile<volatile _Tp> {typedef _Tp type;};

当然,详细的还有下面的这些,从名称就可以知道具体使用:

template <class T> struct remove_const;
template <class T> struct remove_volatile;
template <class T> struct remove_pointer;
template <class T> struct remove_extent;
...

这里就不做过多的介绍

4. 实例

#include <iostream>
#include <type_traits>

typedef std::decay<int>::type A;           // int
typedef std::decay<int&>::type B;          // int
typedef std::decay<int&&>::type C;         // int
typedef std::decay<const int&>::type D;    // int
typedef std::decay<int[2]>::type E;        // int*
typedef std::decay<int(int)>::type F;      // int(*)(int)

typedef int X[3];

int main() {
  std::cout << std::boolalpha;
  std::cout << "typedefs of int:" << std::endl;
  std::cout << "A: " << std::is_same<int,A>::value << std::endl;
  std::cout << "B: " << std::is_same<int,B>::value << std::endl;
  std::cout << "C: " << std::is_same<int,C>::value << std::endl;
  std::cout << "D: " << std::is_same<int,D>::value << std::endl;
  std::cout << "E: " << std::is_same<int,E>::value << std::endl;
  std::cout << "F: " << std::is_same<int,F>::value << std::endl;

  return 0;
}

运行结果:

typedefs of int:
A: true
B: true
C: true
D: true
E: false
F: false

5. 总结

std::decay 主要是弱化一些类型,说白了就是通过typedef 的方式去除掉引用、cv等属性。一般std::decay 与std::is_same 配合使用,确认基础类型。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值