创建constexpr类枚举类型,解决类内同类型static constexpr成员编译报错问题
解决方案
你遇到的是类内定义自身类型constexpr静态成员时,类还未完成定义导致类型不完整的问题,可通过分离静态constexpr成员的声明与定义解决,兼容C++17及以上标准,完全满足你的使用要求:
template <typename Tag> class TypedBool { bool value; explicit constexpr TypedBool(bool b) noexcept : value(b) {} public: // 类内仅做constexpr声明,不需要初始化 static constexpr TypedBool no; static constexpr TypedBool yes; explicit constexpr operator bool() const noexcept { return value; } constexpr TypedBool operator!() const noexcept { return TypedBool{!value}; } }; // 类外完成constexpr定义,此时TypedBool已为完整字面类型 template <typename Tag> constexpr TypedBool<Tag> TypedBool<Tag>::no{false}; template <typename Tag> constexpr TypedBool<Tag> TypedBool<Tag>::yes{true}; // 定义你的类型安全布尔 using FooEnabled = TypedBool<struct FooEnabledTag>;
验证使用效果
- 编译期判断正常:
if constexpr (static_cast<bool>(FooEnabled::yes)) { // 该分支可正常在编译期生效 } - auto推导类型正确,不存在类型不匹配问题:
auto x = FooEnabled::yes; // 传入期望FooEnabled类型的lambda也能编译通过 [](FooEnabled& val) { val = !val; }(x);
原理说明
类内声明静态constexpr成员时,仅要求类型是可被引用的,不需要完整类型;等到类外执行成员定义的阶段,类已经闭合完成定义,属于合法的字面类型,完全满足constexpr变量的定义要求。
因为TypedBool是模板类,其静态成员的类外定义放在头文件中也不会产生多重定义冲突,无需额外处理。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

