[英]Nested generation of comparison operator with three-way operator?
Consider the following two overload operator<=>
for S
:考虑
S
的以下两个重载operator<=>
:
#include <compare>
struct S {};
int operator<=>(S, int) { return 0; } #1
S operator<=>(S, S) { return {}; } #2
If I compare an object S
with an int
, the #1
will generate the right operators for me, so expression like S{} <= 0
, 0 < S{}
or 0 <=> S{}
would be just fine .如果我将object
S
与int
进行比较, #1
将为我生成正确的运算符,因此像S{} <= 0
、 0 < S{}
或0 <=> S{}
这样的表达式就可以了。
But if I compare an object S
with other object S
:但是,如果我将 object
S
与其他 object S
进行比较:
S{} < S{};
Then this will be rewritten as (S{} <=> S{}) < 0
.然后这将被重写为
(S{} <=> S{}) < 0
。 Since (S{} <=> S{})
will return an other S
, we back to the origin problem: S
compare with a int
.由于
(S{} <=> S{})
将返回另一个S
,我们回到原点问题: S
与int
进行比较。 At this time, we don't have operator<(S, int)
, so #1
would generate the right operator for me.目前,我们没有
operator<(S, int)
,所以#1
会为我生成正确的运算符。
But surprisingly, none of the three compilers do this to me.但令人惊讶的是,三个编译器都没有对我这样做。 GCC, Clang, and MSVC all reject
S{} < S{}
with the same error message: GCC、Clang 和 MSVC都拒绝
S{} < S{}
并显示相同的错误消息:
no match for 'operator<' (operand types are 'S' and 'int')
This makes me frustrated.这让我很沮丧。 Since the
#1
actually exists.因为
#1
确实存在。 Why the nested generation of the operator are not occurring here?为什么这里没有发生操作符的嵌套生成? What does the standard say?
标准是怎么说的? Is there a static constraint violation?
是否存在 static 约束违规?
This is ill-formed, although admittedly the error message is quite confusing.这是格式错误的,尽管错误消息确实令人困惑。
The rule, from [over.match.oper]/8 is (emphasis mine):来自[over.match.oper]/8的规则是(强调我的):
If a rewritten
operator<=>
candidate is selected by overload resolution for an operator@
,x @ y
is interpreted as0 @ (y <=> x)
if the selected candidate is a synthesized candidate with reversed order of parameters, or(x <=> y) @ 0
otherwise, using the selected rewrittenoperator<=>
candidate.如果通过重载决策为运算符
@
选择了重写的operator<=>
候选者,如果所选候选者是具有相反参数顺序的合成候选者,则x @ y
被解释为0 @ (y <=> x)
,或者(x <=> y) @ 0
否则,使用选定的重写operator<=>
候选。 Rewritten candidates for the operator@
are not considered in the context of the resulting expression.在结果表达式的上下文中不考虑运算符
@
的重写候选。
The expression S{} < S{}
is going to resolve to the rewritten candidate (S{} <=> S{}) < 0
.表达式
S{} < S{}
将解析为重写后的候选(S{} <=> S{}) < 0
。 The resulting expression will not consider rewritten candidates in its lookup.生成的表达式在其查找中不会考虑重写的候选者。 So when we do
S{} < 0
, that is going to look for just an operator<
, and not also operator<=>
.因此,当我们执行
S{} < 0
时,将只查找operator<
,而不是operator<=>
。 It can't find such a thing, so the expression is ill-formed.它找不到这样的东西,所以表达式是不正确的。
<source>:8:14: error: no match for 'operator<' (operand types are 'S' and 'int')
8 | auto x = S{} < S{};
| ~~~~^~~~~
In that sense, the error is literally true: there is no match for, specifically operator<
with those operands.从这个意义上说,错误是真的:没有匹配,特别是
operator<
与这些操作数。 Although it would help if the error message had quite a bit more context explaining why it's looking for that (and I submitted a request to that effect in 99629 ).虽然如果错误消息有更多的上下文来解释它为什么要寻找它(并且我在99629中提交了一个请求),这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.