枚举运算符不工作
enum operators not working
我的应用程序有很多需要各种支持函数的位字段枚举(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 将不起作用。 基本上,模板推导不适用于::...那么,将枚举用作位域的基类(或以其他方式解决问题(的正确方法是什么? 我不想使用命名空间技巧,因为我需要类型来参与模板推导。 任何人?
你需要将它们声明为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);
(变化在第三行的最后一句话(
这是我发现的使运算符 1 和 2 工作的最佳解决方案。 如果您知道更好的方法,请发布!
//operator #1
template <typename T, typename = std::enable_if<std::is_enum<T>::value>>
inline constexpr T operator|(const T L, const T R)
{
return static_cast<T>(static_cast<EnumUnderlying_t>(L) | static_cast<EnumUnderlying_t>(R));
}
//operator #2
template <typename T, typename = std::enable_if<std::is_enum<T>::value>>
inline constexpr T & operator|=(T & l, const T R)
{
l = static_cast<T>(static_cast<EnumUnderlying_t>(l) | static_cast<EnumUnderlying_t>(R));
return l;
}
相关文章:
- 布尔比较运算符是如何在C++中工作的
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- C++编程:运算符重载中的引用如何工作?
- 编译"运算符删除"时C++编译器如何工作?
- C++,()运算符重载,它的工作是什么
- 错误:三元运算符无法在对象中正常工作"cout"
- 为什么重载运算符"="动态数组的类上无法正常工作?C++
- 为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
- C++自定义删除运算符不能正常工作?
- 为什么我的模运算符无法正常工作?
- ostream_iterator运算符=在pair<int,int>上失败,但在包装器类上工作。我不能为成对<>重载运算符<<吗?
- 变量地址的运算符[]是如何工作的
- 为什么我的类工作正常,即使在返回垃圾值作为赋值运算符和空复制构造函数的返回之后
- 如何使用while循环找到GCD?模数运算符是如何工作的
- 让类与运算符一起工作更简单的方法
- 枚举运算符不工作
- 为什么运算符"new"需要指针才能工作?
- 有人可以解释速记赋值运算符的实际工作原理吗?
- 不工作 复制分配运算符
- 返回对象如何与分配运算符一起工作