【发布时间】:2021-06-19 23:59:56
【问题描述】:
考虑具有相同&& 限定符和不同const 限定符的两个operator== 重载的struct S:
struct S {
bool operator==(const S&) && {
return true;
}
bool operator==(const S&) const && {
return true;
}
};
如果我将这两个S 与operator== 进行比较:
S{} == S{};
gcc 和 msvc 接受此代码,clang rejects 它与:
<source>:14:7: error: use of overloaded operator '==' is ambiguous (with operand types 'S' and 'S')
S{} == S{};
~~~ ^ ~~~
为什么 clang 认为这里有一个模棱两可的重载解决方案?在这种情况下,非 const 不应该是最佳人选吗?
同样,如果我将两个S 与合成的operator!= 进行比较:
S{} != S{};
gcc 仍然接受这个代码,但是 msvc 和 clang doesn't:
<source>:14:7: error: use of overloaded operator '!=' is ambiguous (with operand types 'S' and 'S')
S{} != S{};
~~~ ^ ~~~
合成的operator!= 突然导致msvc 的歧义似乎很奇怪。哪个编译器是对的?
【问题讨论】:
-
(S&&, S&&)的候选人是(S&&, const S&&)、(const S&&, const S&&)、(const S&&, S&&)/*rewritten*/。每个S&&都比const S&&更匹配,所以调用应该是模棱两可的IMO。 -
我也认为 Clang 是正确的,正如@Jarod42 所指出的那样。
S{}不是 const,但表达式S{} == S{}需要在最佳匹配、每个参数的参数、例如arg1和arg2、四个综合重载和 @ 987654348@(S&&, const S&&)对(S&&, S&&)是模棱两可的(反之,对于arg2)。如果我们比较使用函数调用表示法(Clang 接受)S{}.operator(S{}),重载集将是(const S&&, const S&)和(S&&, const S&),后者无疑是最佳匹配。
标签: c++ operator-overloading comparison language-lawyer c++20