【问题标题】:redefinition of comparison operators of enums [closed]重新定义枚举的比较运算符 [关闭]
【发布时间】:2016-02-05 11:45:53
【问题描述】:

为什么允许以下运算符重载?

enum class e { a, b, };

constexpr
bool operator == (e l, e r)
{ return l != r; }

constexpr
bool operator != (e l, e r)
{ return !(l == r); }

static_assert(e::a == e::b, "==");
static_assert(e::a != e::a, "!=");

Live example (C++11).

Live example (C++03).

我总是将enums 视为内置类型。我不能为指向我的自定义类型的指针重新定义operator ==(但我想要!),但可以为相同类型的一对enum 执行此操作。但是两者都有内置版本的operator ==operator !=

这种(似乎是错误的)事情的可能目的是什么?如何利用它获利?

【问题讨论】:

  • 这有什么问题?
  • 我的意思是这样定义操作符没有多大意义,但除此之外对我来说看起来完全没问题
  • @tobi303 我总是将enums 视为内置类型。我不能为int 重新定义operator ==,但可以为enum 重新定义。
  • 我猜你想知道可能的递归问题?
  • @JoachimPileborg 没有递归。第二个运算符未前向声明。

标签: c++ c++11 enums operator-overloading


【解决方案1】:

看来,这里的问题是您认为(无作用域的)枚举等于整数。正如我在评论中所说,枚举值可以从整数转换或转换为整数,但它们仍然是一种自定义类型,您可以为其重载运算符。

参见例如this unscoped enumeration referencethis reference on implicit conversions(尤其是关于 integral promotionintegral conversions 的部分)。

【讨论】:

  • 还有哪些自定义类型 T 内置了operator == (T, T)operator != (T, T)? (我认为它们不是custom)。
  • @Orient Enums 没有内置 operator == 。他们在 operator int() 中有一个构建,当您尝试比较 2 个枚举时会调用 operator ==(int, int)
  • @Orient 它没有内置比较运算符,与int 不同。再说一遍:枚举是自定义类型!另请参阅this post with a quote from the creator of C++
  • 代码不变量也适用于范围枚举。
  • @rozina 为简洁起见,请参阅上次编辑(class 现在未注释)。如您所见,现在禁止隐式转换为 std::underlying_type_t,但仍然没有一个 static_assertion 失败并且代码格式正确。
【解决方案2】:

枚举是用户定义的类型,就像结构、类或联合一样。

您的代码有效,因为一个运算符在声明时看不到另一个运算符,因此对 ==!= 的调用之一调用默认值并将它们作为整数类型进行比较。

当然,它提供了一个默认的==,但你可以根据需要覆盖它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2014-03-05
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多