代码之家  ›  专栏  ›  技术社区  ›  bur

哪些是传统的标志运算符?

  •  -2
  • bur  · 技术社区  · 6 年前

    我已经定义了一个枚举,我想用它来存储变量中的标志。其目的是能够设置几个标志,并能够检查设置了哪些标志。

    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
    

    我选的 <= != 任意地。我知道它们通常有完全不同的含义。所以我想知道:

    • 还是使用函数而不是运算符重载更好?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Christophe    6 年前

    大多数代码读者(甚至你未来的自己)都会感到非常困惑,因为你给操作符的含义与标准操作符不一致。例如:

    • !(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()