xmh0511
xmh0511

Reputation: 7369

which are the rewritten candidates for != operator

The relevant rule in the standars says:
over.match.oper#3.4.3

The rewritten candidate set is determined as follows:

  1. For the relational ([expr.rel]) operators, the rewritten candidates include all non-rewritten candidates for the expression x <=> y.
  2. 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.
  3. For the != operator ([expr.eq]), the rewritten candidates include all non-rewritten candidates for the expression x == y.
  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.
  5. 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

Answers (1)

N. Shead
N. Shead

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

  • all non-rewritten candidates for x == y, and also
  • synthesized candidates for non-rewritten candidates for y == 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

Related Questions