C++ 位字段枚举的重载求反运算符

C++ 位字段枚举的重载求反运算符,c++,enums,operator-overloading,C++,Enums,Operator Overloading,我有一个类,它有两个成员,它们是enum类型的位字段。我想为enum重载否定运算符,因为出于实现原因,我不能使用实际为零的值作为null状态。但是它看起来像操作符”,尽管如果值不是位字段,它似乎可以正常工作。我缺少的位字段有什么特别的地方吗 下面是一个测试代码(具有相同数量的enum值): 从具有位字段成员的测试的输出中可以看出,“(!”)不会被打印,积分值会被求反,而不是与标志::no_字段进行比较 Edit:我提交了一个GCC错误。@AndyG我的观点是测试(!f.a)不会打印bool操作符

我有一个类,它有两个成员,它们是
enum
类型的位字段。我想为
enum
重载否定运算符,因为出于实现原因,我不能使用实际为零的值作为null状态。但是它看起来像
操作符,尽管如果值不是位字段,它似乎可以正常工作。我缺少的位字段有什么特别的地方吗

下面是一个测试代码(具有相同数量的
enum
值):

从具有位字段成员的测试的输出中可以看出,“(!”)不会被打印,积分值会被求反,而不是与
标志::no_字段
进行比较


Edit:我提交了一个GCC错误。

@AndyG我的观点是
测试(!f.a)
不会打印
bool操作符!(flags::field)
,所以我的函数没有被使用,我想知道原因。我明白了。应该仔细阅读。我认为这是一个GCC错误,可能与用于枚举或位字段或两者的底层存储有关。当clang和MSVC都按预期运行时,这有助于我对GCC错误的声明。似乎是这样。我用叮当声试了一下,没有这个问题。
#include <iostream>

#define TEST(var) std::cout << #var " = " << var << std::endl;

struct flags {
  enum field { f0, f1, no_field };
  field b0 : 4;
  field b1 : 4;
  field a0, a1;
};

inline bool operator!(flags::field f) {
  std::cout << "(!) ";
  return f == flags::no_field;
}

int main() {
  flags f;
  f.b0 = flags::f0;
  f.b1 = flags::f1;
  f.a0 = flags::f0;
  f.a1 = flags::f1;

  std::cout << "******** test enum values" << std::endl;

  TEST( flags::f0 ) // 0
  TEST( flags::f1 ) // 1
  TEST( flags::no_field ) // 2
  TEST( !flags::f0 ) // (!) 0
  TEST( !flags::f1 ) // (!) 0
  TEST( !flags::no_field ) // (!) 1

  std::cout << "\n******** test regular members" << std::endl;

  TEST( f.a0 ) // 0
  TEST( f.a1 ) // 1
  TEST( !f.a0 ) // (!) 0
  TEST( !f.a1 ) // (!) 0

  std::cout << "\n******** test bit field members" << std::endl;

  TEST( f.b0 ) // 0
  TEST( f.b1 ) // 1
  TEST( !f.b0 ) // expected "(!) 0", but got "1"
  TEST( !f.b1 ) // expected "(!) 0", but got "0"
}
******** test enum values
flags::f0 = 0
flags::f1 = 1
flags::no_field = 2
!flags::f0 = (!) 0
!flags::f1 = (!) 0
!flags::no_field = (!) 1

******** test regular members
f.a0 = 0
f.a1 = 1
!f.a0 = (!) 0
!f.a1 = (!) 0

******** test bit field members
f.b0 = 0
f.b1 = 1
!f.b0 = 1
!f.b1 = 0