c++ - 方便地为枚举定义按位运算符以创建位标志

标签 c++ enums

为了定义一个枚举用作位标志,可以定义枚举本身,使用适当的值,并为枚举类型定义按位运算符,如下所示。

enum ENUM_TYPE
{
    ET_VAL1    = 1L << 0,
    ET_VAL2    = 1L << 1
}

inline ENUM_TYPE operator& (ENUM_TYPE _a, ENUM_TYPE _b) 
{return ENUM_TYPE(static_cast<int>(_a) & static_cast<int>(_b));}

/* similarly for |, ^, ~, |=, &=, ^= */

问题是按位运算符的定义占用大量空间,使代码难以阅读,而且编写起来很烦人,特别是如果定义了各种枚举。

可以在头文件中创建一个模板,如下所示,并在需要时简单地包含它。但是,这会带来在未明确定义位运算符的类型上使用位运算符的风险。

template<typename ENUM_T>
inline ENUM_T operator& (ENUM_T _a, ENUM_T _b) 
{return ENUM_T(static_cast<int>(_a) & static_cast<int>(_b));}

也可以创建宏,如下所示。这似乎很容易出错?

#define BITWISE_AND(TYPE) inline TYPE operator& (TYPE _a, TYPE _b)\
        {return TYPE(static_cast<int>(_a) & static_cast<int>(_b));}

#define BITWISE_ALL(TYPE) BITWISE_AND(TYPE) /* and others */

执行上述操作的“正确”方法是什么?各种标志定义是一种代码味道吗?生产代码中通常会做什么?

最佳答案

不是您问题的直接答案,但您是否考虑过使用 std::bitset<N> ?我发现这是一种定义和使用标志的便捷方法。例如:

#include <iostream>
#include <bitset>


using Flag = std::bitset<3>;

const Flag FOO("001");
const Flag BAR("010");
const Flag BAZ("100");

int main() {

  Flag thing("011");

  if((thing & FOO) == FOO) {
    std::cout << "thing has foo\n";
  } else {
    std::cout << "thing does not have foo\n";
  }

  if((thing & BAR) == BAR) {
    std::cout << "thing has bar\n";
  } else {
    std::cout << "thing does not have bar\n";
  }


  if((thing & BAZ) == BAZ) {
    std::cout << "thing has baz\n";
  } else {
    std::cout << "thing does not have baz\n";
  }


}

示例输出:

$ g++ example.cpp -std=c++14 -Wall -Wextra
$ ./a.out
thing has foo
thing has bar
thing does not have baz

对于 more information on std::bitset<N> in cppreference.com ,它被描述为:

The class template bitset represents a fixed-size sequence of N bits. Bitsets can be manipulated by standard logic operators and converted to and from strings and integers.

关于c++ - 方便地为枚举定义按位运算符以创建位标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35852282/

相关文章:

java - 枚举常量中局部变量的范围

python - Mypy 无法推断从列表变量创建的枚举

enums - 等同于 C 枚举的 Common Lisp

c++ - 使用 mingw 和 g++ 编译器

c++ - 构造函数的顺序 - 链式继承

c++ - _DebugHeapDelete 终止时访问冲突

java - 在Java中,表示枚举类型的字段常量的对象实例是否仅在首次访问时实例化?

python - 如何优雅地找到 Python 枚举中的下一个和上一个值?

c++ - 如何在 C++ Builder XE5 跨平台中获取 TAlphaColor 的 RGB 分量?

c++ - 检查在模板第一个参数之后声明的函数是否为 NULL(传递 vector 和数组)