【发布时间】:2022-01-09 23:08:41
【问题描述】:
我一直使用enum class FooEnabled : bool { no, yes }; 作为创建类型安全bools 的一种方式。它工作得很好,除了我想添加对bool 的显式转换、operator! 等布尔运算符等。我可以这样做:
template <typename Tag>
class TypedBool {
bool value;
explicit constexpr TypedBool(bool b) noexcept : value(b) {}
public:
static inline TypedBool no{false};
static inline TypedBool yes{true};
explicit constexpr operator bool() const noexcept { return value; }
constexpr TypedBool operator!() const noexcept { return TypedBool{!value}; }
// ...
};
using FooEnabled = TypedBool<struct FooEnabledTag>;
这很好用,但是 no 和 yes 不是 constexpr,所以我不能做 if constexpr (FooEnabled::yes) { 的例子。如果我将no 和yes 改为static constexpr,clang 会感到不安,因为TypedBool 不是文字类型。这似乎是因为 TypedBool 在那个时候是不完整的。
最简单的例子是struct S { static constexpr S s; };,它给出了
error: constexpr variable cannot have non-literal type 'const S'
struct S { static constexpr S s; };
^
note: incomplete type 'const S' is not a literal type
note: definition of 'S' is not complete until the closing '}'
struct S { static constexpr S s; };
有没有办法解决这个问题?我可以让no 和yes 成为隐式转换为TypedBool<Tag> 的不同类型,但这看起来很奇怪,因为那样auto x = FooEnabled::yes; 会使x 不是FooEnabled,所以
auto x = FooEnabled::yes;
[](FooEnabled& x) { x = !x; }(x);
会失败。
有没有办法让一个类包含属于它自己类型的static constexpr 成员?我开始想到的解决方案似乎都太丑陋了(而且这些解决方案也有constexpr 的限制)。
【问题讨论】:
-
您始终可以创建
yes和noconstexpr 函数。 -
是的,但这不是类似枚举的 API。
标签: c++ constexpr type-safety