传统的 Flag 运算符有哪些?
Which are the conventional Flag operators?
我定义了一个枚举,用于在变量中存储标志。目的是能够设置多个标志,并能够检查设置了哪些标志。
为此,我需要两个操作:一个是找出 a
是否在 b
中,另一个是找出 a
是否在 中不是 b
中的 。我使用运算符重载来实现它们。我随便选了<=
和!=
:
enum Flag { NoFlags, B, C, D=4 };
inline Flag operator |(Flag a, Flag b) {
return static_cast<Flag >(static_cast<int>(a) | static_cast<int>(b)); }
inline bool operator <=(Flag a, Flag b) { return a == (a & b); }
inline bool operator !=(Flag a, Flag b) { return !(a<=b); }
这很好用。例如:
Flag flags1 = A|C;
Flag flags2 = B|D;
Flag flags3 = NoFlags|A|B|C|D;
A <= flags1 //true
A != flags2 //true
C != flags3 //false
B <= flags1 //false
我随便选了<=
和!=
。我知道它们通常具有完全不同的含义。所以我想知道:
是否存在使用其他运算符来表示这两个操作的普遍接受的做法?
或者使用函数而不是运算符重载会更好吗?
你的代码的大多数读者(甚至可能是你未来的自己)会感到很困惑,因为你赋予运算符的含义与标准运算符不一致。例如:
!(a <= b)
预计与 a>b
相同
!(a != b)
预计与 a==b
相同
flags1 != flags3
不再意味着在两个变量中设置了完全相同的标志
因此,根据 principle of least astonishment,我强烈反对您的选择。
标志操作符的常见做法是使用|
设置标志,&
结合~
重置标志,&
测试标志.但这是完成的,假设可预测的按位操作,而不是像您那样的更高级别的接口。
在你的情况下,我建议使用函数而不是运算符,并让函数名称清楚地表达你的意图(例如 is_included()
)。我什至建议考虑使用成员函数 enum classes 以获得更好的封装。
由于您似乎将 Flag
变量视为一组组合的独立标志,如果您正在寻找一致且已知的命名方案,则可以从 std::set
接口中获得启发(例如 insert()
、find()
、contains()
、merge()
等...)。
我定义了一个枚举,用于在变量中存储标志。目的是能够设置多个标志,并能够检查设置了哪些标志。
为此,我需要两个操作:一个是找出 a
是否在 b
中,另一个是找出 a
是否在 中不是 b
中的 。我使用运算符重载来实现它们。我随便选了<=
和!=
:
enum Flag { NoFlags, B, C, D=4 };
inline Flag operator |(Flag a, Flag b) {
return static_cast<Flag >(static_cast<int>(a) | static_cast<int>(b)); }
inline bool operator <=(Flag a, Flag b) { return a == (a & b); }
inline bool operator !=(Flag a, Flag b) { return !(a<=b); }
这很好用。例如:
Flag flags1 = A|C;
Flag flags2 = B|D;
Flag flags3 = NoFlags|A|B|C|D;
A <= flags1 //true
A != flags2 //true
C != flags3 //false
B <= flags1 //false
我随便选了<=
和!=
。我知道它们通常具有完全不同的含义。所以我想知道:
是否存在使用其他运算符来表示这两个操作的普遍接受的做法?
或者使用函数而不是运算符重载会更好吗?
你的代码的大多数读者(甚至可能是你未来的自己)会感到很困惑,因为你赋予运算符的含义与标准运算符不一致。例如:
!(a <= b)
预计与a>b
相同
!(a != b)
预计与a==b
相同
flags1 != flags3
不再意味着在两个变量中设置了完全相同的标志
因此,根据 principle of least astonishment,我强烈反对您的选择。
标志操作符的常见做法是使用|
设置标志,&
结合~
重置标志,&
测试标志.但这是完成的,假设可预测的按位操作,而不是像您那样的更高级别的接口。
在你的情况下,我建议使用函数而不是运算符,并让函数名称清楚地表达你的意图(例如 is_included()
)。我什至建议考虑使用成员函数 enum classes 以获得更好的封装。
由于您似乎将 Flag
变量视为一组组合的独立标志,如果您正在寻找一致且已知的命名方案,则可以从 std::set
接口中获得启发(例如 insert()
、find()
、contains()
、merge()
等...)。