繁体   English   中英

C++20 比较:关于不明确的反向运算符的警告

[英]C++20 comparison: warning about ambiguous reversed operator

考虑这个有效的 C++17 示例:

struct A {
   bool operator==(const A&);
};


int main() {
   return A{} == A{};
}

使用 -std=c++20 在 clang 中编译时,它给出

<source>:7:15: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'A' and 'A') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]

   return A{} == A{};

          ~~~ ^  ~~~

<source>:2:9: note: ambiguity is between a regular call to this operator and a call with the argument order reversed

   bool operator==(const A&);

这个警告是否意味着 C++20 不允许使用典型的比较运算符来比较两个相同类型的对象? 什么是正确的选择? 这种情况在未来的选秀中会发生变化吗?

这个警告是否意味着 C++20 不允许使用典型的比较运算符来比较两个相同类型的对象? 什么是正确的选择? 这种情况在未来的选秀中会发生变化吗?

这并不是一个典型的比较运算符,它已经有点错误了——因为它只允许一侧有一个const对象(即使没有任何语言更改,您的类型A也不满足新的equality_comparable概念)。

你必须这样写:

struct A {
   bool operator==(const A&) const;
//                          ^^^^^^
};

这是 C++20 的最终规则。


具体问题是,在 C++20 中,比较运算符添加了重写和反向候选的新概念。 所以查找表达式a == b也将匹配像b == a这样的操作符。 在典型情况下,这意味着您必须编写更少的运算符,因为我们知道相等是可交换的。

但是如果你有一个常量不匹配,你最终会得到这两个候选人:

bool operator==(/* this*/ A&, A const&); // member function
bool operator==(A const&, /* this*/ A&); // reversed member function

带有两个A类型A参数。 第一个候选人在第一个参数中更好,第二个候选人在第二个参数中更好。 两个候选人都不比另一个好,因此模棱两可。

重载决议的一般规则是,每个参数类型必须分别至少与所选函数的参数类型与任何其他参数的类型接近:

struct A {A(int);};
void f(long,int);   // #1
void f(int,A);      // #2
void g() {f(0,0);}  // error: ambiguous

#2 的第二个参数的更糟糕的转换并不能弥补第一个参数的intlong转换。

在 C++20 中,添加了各种重写规则以消除编写如此多几乎相同的比较运算符重载的需要。 虽然手写的“反向候选”和相同的编译器生成的那些之间的微不足道的歧义是由更喜欢真实函数的决胜局规则处理的,但这(再次)不足以弥补任何参数的更糟糕的转换。

根据公认的 (C++17) 实践仔细编写的比较运算符很少会与此发生冲突,但像这样的有问题的签名(使用非对称const )很可能会出现问题(以新的方式)。 希望能找到比这个扩展引起的更多的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM