C++泛型编程学习 std::declval void_t

本文深入探讨了C++中的类型检查与元编程技术,包括如何使用std::declval和std::void_t来判断类型是否存在,以及如何通过模板元编程实现对类成员函数、变量的检测。此外,还介绍了如何利用这些技术进行类型安全的编程,如检查类对象是否可拷贝赋值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void_t 判断 类型是否存在

class T
{
    public:
    int test(){int a = 1;}
}
std::declval:将任何一个类型T转换成引用类型, 在不创建对象的情况下能达到创建对像的效果,
可以使 decltype 表达式中不必经过构造函数就能使用成员函数
eg: decltype(std::declval<T>.test())   //int 这里没有创建T的对象, 也没有执行a = 1;

给定一个变量或表达式,decltype能够推导出他的类型。最重要的是能够不需要计算表达式就可以推导出表达式所得值的类型。
struct Default { int foo() const { return 1; } };
struct NonDefault
{
    NonDefault(const NonDefault&) { }
    int foo() const { return 1; }
}
decltype(Default().foo()) n1 = 1;                   // type of n1 is int



//判断是否有这种类型
#define _HAS_TYPE_MEM_(parMTpNm)\
template<typename T, typename U = std::void_t<>>\
struct HTM_##parMTpNm: std::false_type{}; \
template<typename T>\
struct HTM_##parMTpNm<T, std::void_t<typename T::parMTpNm>>:std::true_type{};

eg: std::cout<< _HAS_TYPE_MEM_<classname>::value << std::endl;
//or std::cout<< HTM_type<classname>::value << std::endl;
   

//判断类是否有这种变量
#define _HAS_TYPE_VAR_(parMTpNm)\
template<typename T, typename U = std::void_t<>>\
struct HTM_##parMTpNm: std::false_type{}; \
template<typename T>\
struct HTM_##parMTpNm<T, std::void_t<decltype(T::var)>>:std::true_type{};

//判断类中是否存在成员函数
#define _HAS_TYPE_FUN_(parMTpNm)\
template<typename T, typename U = std::void_t<>>\
struct HTM_##parMTpNm: std::false_type{}; \
template<typename T>\
struct HTM_##parMTpNm<T, std::void_t<decltype<T>().parMTpNm>>:std::true_type{};

//
typename = int typename = char 等
优先于
typename = void 
///

/// is_copy_assignable() 类对象是否可以拷贝复值
template<typename T, typename U = std::void_t<>>
struct ISCopyAssignable:std::false_type
{
};
template <typename T>
struct ISCopyAssignable<T, std::void_t<decltype(std::declval<T&>()/*临时变量*/ = std::declval<const T&>())> >:std::true_type
{
};

std::declval<T&>()/*临时变量*/ = std::declval<const T&>()  它类似 T& operator= (const T &), 与前面一一对应,  结果为T&
//





eg:
template<typename T, typename U, typename V = std::void_t<>>
struct IfCanAdd: std::false_type
{}

template<typename T, typename U>
struct IfCanAdd<T, U, std::void_t<decltype(std::declval<T>() + std::declval<U>())>>:std::true_type
{
    
}
/*
    template<typename T, typename U>
    struct VerAddRet
    {
        //    using type = decltype(T() + U())
        using type = decltype(std::declval<T>() + std::declval<U>());
    }
*/
template<typename T, typename U, bool = IfCanAdd<T, U>::value>//泛
struct VerAddRet
{
    using type = decltype(std::declval<T>() + std::declval<U>());
}

template<typename T, typename U>//特
struct VerAddRet<T, U, false>
{
   
}

template<typename T, typename U>
std::vector<typename VerAddRet<T, U>::type> operator+(std::verctor<T> const&, std::verctor<T> const&)
{
    std::verctor<typename VerAddRet<T, U>::type> tmpvec;
    return tmpvec;
}

struct elemC
{
      elemC(int i);
      elemC operator+(const elemC&t); 
}
std::vector<elemC> vea;
std::vector<elemC> veb;
vea + veb;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值