Reputation: 7369
The relevant rule in the standars says:
over.match.oper#3.4.3
The rewritten candidate set is determined as follows:
- For the relational ([expr.rel]) operators, the rewritten candidates include all non-rewritten candidates for the expression x <=> y.
- For the relational ([expr.rel]) and three-way comparison ([expr.spaceship]) operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate for the expression y <=> x.
- For the != operator ([expr.eq]), the rewritten candidates include all non-rewritten candidates for the expression x == y.
- For the equality operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate for the expression y == x.
- For all other operators, the rewritten candidate set is empty.
Consider the following code:
#include <iostream>
struct Data{
bool operator ==(int c){
return true;
}
};
int main(){
Data d;
bool r = 0 != d; // should be ill-formed
}
I don't know why the code can be compiled by the compiler. IMO, the rewritten candidates for expression 0!=d
should include all non-rewritten candidates for the expression x == y. My understanding of the wording non-rewritten candidates is, consider any candidates other than the rewritten candidates for the expression x==y for operation x != y. After all, bullet 4 is used to form a rewritten candidate set. So, the fourth bullet should not continue to apply to the x==y
that has been rewritten for the original expression x!=y
. In my example, the rewritten candidate set for 0!=d
contains only that for 0==d
, which should not consider any rewritten candidate for d==0
;
The relevant rule in this page for wording non-rewritten has a similar interpretation with mine. (exclude rewritten candidate)
For the != operator ([expr.eq]), the rewritten candidates include all member, non-member, and built-in candidates for the expression x == y.
However, continue to look at the next paragraph, that is:
If a rewritten operator== candidate is selected by overload resolution for an operator @, its return type shall be cv bool, and x @ y is interpreted as:
- if @ is != and the selected candidate is a synthesized candidate with reversed order of parameters, !(y == x),
Since the rewritten candidate for !=
cannot be continued to rewrite, how could it have a synthesized candidate with reversed order of parameters? I don't know why. How to interpret the rule of the rewritten candidates for !=
, particularly the wording non-rewritten candidate and the last rule?
Upvotes: 3
Views: 237
Reputation: 3938
I suspect that this is granted by [over.match.oper]/3.4.4:
For the equality operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate for the expression y == x.
Equality operators are both operator==
and operator!=
. Also note "synthesized" is not synonymous with "rewritten": the four sets of candidates are member candidates, non-member candidates, built-in candidates, and rewritten candidates. A synthesized candidate merely belongs to one of these sets (in this case the set of rewritten candidates).
As such, my understanding is the rewritten candidates for x != y
include both
x == y
, and alsoy == x
.So the synthesized candidate for y == x
is also rewritten candidate. Then [over.match.oper]/9.1 kicks in:
if
@
is!=
and the selected candidate is a synthesized candidate with reversed order of parameters,!(y == x)
That is, if the rewritten candidate selected is the above synthesized candidate of y == x
, then the result will be !(y == x)
.
Upvotes: 5