decay declval decltype使用

#include <iostream>
#include <utility> // std::declval
#include <type_traits>

class AbstractBase{
public:
    virtual int value() = 0;
};

class Derived: public AbstractBase{
public:
    Derived() = delete;
    Derived(int age):age_(age){}
    virtual int value(){ return age_;}
private:
    int age_{0};
};

// declval:返回一个类型的右值引用,不管该类型有没有默认构造函数、构造函数delete或
// 该类型不可以创建对象(也可以用于抽象基类),一般和decltype一起使用
void Test(){
    // 纯抽象类
    decltype(std::declval<AbstractBase>().value()) abs;// int
    std::cout<<std::is_same<decltype(abs), int>::value<<std::endl;// 1
    
    // 子类没有默认构造函数
    decltype(std::declval<Derived>().value()) der; // int
    std::cout<<std::is_same<decltype(der), int>::value<<std::endl;// 1
    
    decltype(std::declval<Derived>()) r = Derived(10);
    std::cout<<std::is_rvalue_reference_v<decltype(r)><<std::endl; // 1
}


// decay(类型弱化): 为类型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;

void Test2(){
    
    std::cout<<std::is_same_v<std::decay_t<int>, int><<std::endl; // 1
    std::cout<<std::is_same_v<std::decay_t<int&>, int><<std::endl; // 1
    std::cout<<std::is_same_v<std::decay_t<int&&>, int><<std::endl; // 1

    // 去引用和cv
    std::cout<<std::is_same_v<std::decay_t<const int&>, int><<std::endl; // 1

    // 数组到指针
    std::cout<<std::is_same_v<std::decay_t<int[2]>, int*><<std::endl; // 1

    // 函数到指针
    std::cout<<std::is_same_v<std::decay_t<int(int)>, int(*)(int)><<std::endl; // 1

}

// decltype与declval结合使用
// 对与两个不同类型进行相加,根据decltype参数表达式获取结果类型
template<typename T1, typename T2>
struct PlusResultT{
    using Type = decltype(declval<T1>() + declval<T2>());
};

template<typename T1, typename T2>
using PlusResult = PlusResultT<T1, T2>::Type;

void Test3(){
    PlusResult<int, long> res;
    std::cout<<res<<std::endl; // init value 0

    std::cout<<boolalpha;
    std::cout<<is_same< PlusResult<int, long>, int>::value<<std::endl; // false;
    std::cout<<is_same< PlusResult<int, double>, double>::value<<std::endl; // true;
    std::cout<<is_same< PlusResult<int, long>, long>::value<<std::endl; // true;
}
int main(){
    Test();
    Test2();
    Test3();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值