【问题标题】:Why is == operator overload of enum ambiguous in MSVC为什么 == 枚举的运算符重载在 MSVC 中不明确
【发布时间】:2017-11-14 20:34:23
【问题描述】:

以下代码在我检查过的所有编译器(clang、mingw、g++)上都能正常编译,而不是 MSVC。

enum class Foo{BAR};

bool operator==(Foo a, Foo b)
{
    return (int)a & (int)b;
}

int main(int argc, char *argv[])
{
    Foo::BAR==Foo::BAR;
    return 0;
}

MSVC 失败并出现以下错误:

>main.cpp(10): error C2593: 'operator ==' is ambiguous
>main.cpp(3): note: could be 'bool operator ==(Foo,Foo)'
>main.cpp(10): note: while trying to match the argument list '(Foo, Foo)'

任何见解都会很棒,我整天都在摸不着头脑。

我的 MSVC 版本是 14.0,但是我已经使用版本 19.00.23506 在线测试它并出现相同的错误。

但是,版本 19.11.25331.0 不会出现该错误。 那么编译器bug呢?

【问题讨论】:

  • 可能是因为有内置的。
  • 附带说明,如果我必须使用您的operator== 版本,我会感到困惑,因为它不测试相等性。
  • @piwi - 这只是重现模棱两可错误的最少代码,
  • @hippiemancam 哦,好吧,我的错。
  • @StoryTeller 这似乎很合理,如何覆盖这个内置的?另外,有什么想法为什么只有 MSVC 在没有任何警告的情况下抛出错误?

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


【解决方案1】:

对于枚举,有一个内置的比较运算符。当你定义你的时,内置应该是自动隐藏的。

[over.built/1]

代表内置运算符的候选运算符函数 条款 [expr] 中定义的条款在本条款中指定。这些 候选函数参与运算符重载决议 [over.match.oper] 中描述的过程,不用于其他 目的。 [ 注意:因为内置运算符只接受与 非类类型,并且运算符重载决议仅在 操作数表达式最初具有类或枚举类型,运算符 重载决议只能解析为内置运算符 操作数的类类型具有用户定义的转换为 适合运算符的非类类型,或者当操作数具有 枚举类型,可以转换为适合的类型 操作员。另请注意,一些候选运算符函数 本小节中给出的比内置的更宽松 运营商自己。如 [over.match.oper] 中所述,经过 内置运算符由重载决议选择表达式是 符合条款中给出的内置运算符的要求 [expr],因此对于给定的任何附加语义约束 那里。 如果有用户写的同名候选人,并且 参数类型作为内置候选运算符函数, 内置算子函数是隐藏的,不包含在集合中 候选函数。 — 尾注 ]

要回答你的问题,是的,这似乎是一个编译器错误。

【讨论】:

  • 谢谢你,很高兴知道我不只是发疯了。
  • @T.C. - 引用了错误的段落(现已修复),但仍然存在编译器错误。
  • 好多了。但请注意,隐藏是基于精确类型匹配的,可能很脆弱:bool operator==(const Foo&, const Foo&); 不会隐藏内置。
猜你喜欢
  • 2020-01-09
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 2017-12-28
  • 2010-11-24
  • 1970-01-01
相关资源
最近更新 更多