为了定义一个枚举用作位标志,可以定义枚举本身,使用适当的值,并为枚举类型定义按位运算符,如下所示。
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/