C++检查类型是否存在的三种方法

背景

最近沉迷于语法糖,并且最近在做项目的时候,总想着要把代码做的更精致、更严谨一些,就想到了用语法糖来检查类型是否存在,当然了实际开发中应该并不会使用这些。
所以…仅供参考!

方法

样例1

直接检查类的大小是否大于0,因为大家都知道即使是一个空类,它的大小也为1。

class bbb {};

#define TYPE_EXISTS0(T) \
    (sizeof(char(*)[sizeof(T)]) > 0)
    
#define CHECK_TYPE0(ClassName) \
namespace { \
        auto func0 = []() { \
        static_assert(TYPE_EXISTS0(ClassName), #ClassName "Class does not define!"); \
        return true; \
        }(); \
}

CHECK_TYPE0(bbb);

样例2

使用 ​SFINAE(Substitution Failure Is Not An Error)​​ 技术的编译期类型存在性检查工具。(C++11标准)

#include <type_traits>

class bbb {};

template<typename T, typename = void>
struct TYPE_EXISTS1 : std::false_type {};

template<typename T>
struct TYPE_EXISTS1<T, std::void_t<decltype(std::declval<T>())>> : std::true_type {};

#define CHECK_TYPE1(ClassName) \
namespace { \
        auto func1 = []() { \
        static_assert(TYPE_EXISTS1<ClassName>::value, #ClassName "Class does not define!"); \
        return true; \
        }(); \
}

CHECK_TYPE1(bbb);

详解:

  1. std::declval() 的作用​
    在编译期虚构一个 T 类型的右值引用(无需构造函数),等效于 T&&,但可以在不构造对象的情况下使用成员函数/运算符,如果 T 是无效类型(未定义或不完整),此处会触发替换失败。
  2. decltype 的编译时求值​
    decltype(std::declval()) 尝试获取虚构表达式的类型,若 T 是完整类型,返回 T&&;若 T 无效,SFINAE 会跳过该特化
  3. std::void_t 的魔法​
    std::void_t<…> 是一个模板元工具,当内部所有类型有效时生成 void;若 decltype(std::declval()) 有效,则特化版本匹配,继承 std::true_type;否则回退到基础模板的 std::false_type

样例3

同上,也是使用SFINAE(C++98标准)

class bbb {};

template<typename T>
struct TYPE_EXISTS2 {
private:
    template<typename U>
    static char test(typename U*);

    template<typename>
    static long test(...);

public:
    static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(char);
};

#define CHECK_TYPE2(ClassName) \
namespace { \
        auto func2 = []() { \
        static_assert(TYPE_EXISTS2<ClassName>::value, #ClassName "Class does not define!"); \
        return true; \
        }(); \
}

CHECK_TYPE2(bbb);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值