gpt4 book ai didi

c++ - 枚举运算符不工作

转载 作者:太空宇宙 更新时间:2023-11-04 12:46:53 31 4
gpt4 key购买 nike

我的应用程序有很多位域枚举,需要各种支持函数(toString()、fromString()、countSetBits()、isValid() 等)。所以我使用 CRTP 为我需要的一切创建了一个带有静态函数的基类。一切都很好,除了,我无法让按位运算符工作。所以……

为什么运算符 1 和 2 不允许 A 和 B 编译?

运算符 3 和 4 工作,它们在我看来是一样的。 (实际上,4 的实现无法编译,我也可以使用一些帮助..)(C 风格转换仅用于节省空间)

难倒了。请帮忙!

#include <type_traits>

using EnumUnderlying_t = unsigned;

template <typename EnumWrapper_t> struct EnumBitfieldBase {
//CRTP allows for lots of handy static functions eliminating code duplication. For example:
static void test(){
if constexpr (!std::is_same<EnumUnderlying_t, typename std::underlying_type<typename EnumWrapper_t::Enum>::type>::value){
throw;
}
}
//also: toString(), fromString(), countSetBits(), isValid(), largestValidValue(), allBitsSet() etc...
};

//operator #1
template <typename EnumWrapper_t>
inline constexpr typename EnumWrapper_t::Enum operator|(const typename EnumWrapper_t::Enum L, const typename EnumWrapper_t::Enum R) {
return (typename EnumWrapper_t::Enum)((EnumUnderlying_t)L | (EnumUnderlying_t)R);
}

//operator #2
template <typename EnumWrapper_t>
inline constexpr typename EnumWrapper_t::Enum & operator|=(typename EnumWrapper_t::Enum & l, const typename EnumWrapper_t::Enum R) {
return (typename EnumWrapper_t::Enum &)((EnumUnderlying_t &)l |= (EnumUnderlying_t)R);
}

struct Option : public EnumBitfieldBase<Option> {
enum Enum : EnumUnderlying_t {
None = 0,
Lame = 1 << 0,
Boring = 1 << 1,
Stupid = 1 << 2
};
};

/*
//operator #3
inline constexpr Option::Enum operator|(const Option::Enum L, const Option::Enum R) {
return (Option::Enum)((EnumUnderlying_t)L | (EnumUnderlying_t)R);
}

//operator #4
inline constexpr Option::Enum & operator|=(Option::Enum & l, const Option::Enum R) {
return (Option::Enum &)((EnumUnderlying_t &)l | (EnumUnderlying_t)R);
}
*/

int main(void) {
Option::test();
Option::Enum options{ Option::Lame | Option::Boring };//A -works only with c++17...why?
options = (Option::Stupid | Option::Boring);//B -only works with operator #3
options |= Option::Lame;//C -only works with operator #4
if (options & Option::Lame) { /*do something lame*/ }
return 0;
}

更新:好的,我发现运算符 1 和 2 由于“非推导上下文”而无法工作。基本上,模板推导不适用于::... 左侧的某些内容那么基类(或以其他方式解决问题)用作位域的枚举的正确方法是什么?我不想使用 namespace 技巧,因为我需要类型参与模板推导。有人吗?

最佳答案

您需要将它们声明为const 方法;否则它们将只被允许在左值上工作,并且你的常量不是左值(它们是 const,obvioulsy)。

//operator #1
template <typename EnumWrapper_t>
inline constexpr typename EnumWrapper_t::Enum operator|(const typename EnumWrapper_t::Enum L, const typename EnumWrapper_t::Enum R) const {
return (typename EnumWrapper_t::Enum)((EnumUnderlying_t)L | (EnumUnderlying_t)R);

(变化在第三行最后一个字)

关于c++ - 枚举运算符不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51108145/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com