From Jason Turner

[over.match.oper]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwpp810e_/{from.md → to.md} +66 -22
tmp/tmpwpp810e_/{from.md → to.md} RENAMED
@@ -30,11 +30,11 @@ void f() {
30
  ```
31
 
32
  — *end example*]
33
 
34
  If either operand has a type that is a class or an enumeration, a
35
- user-defined operator function might be declared that implements this
36
  operator or a user-defined conversion can be necessary to convert the
37
  operand to a type that is appropriate for a built-in operator. In this
38
  case, overload resolution is used to determine which operator function
39
  or built-in operator is to be invoked to implement the operator.
40
  Therefore, the operator notation is first transformed to the equivalent
@@ -60,21 +60,21 @@ binary operator `@` with a left operand of type *cv1* `T1` and a right
60
  operand of type *cv2* `T2`, four sets of candidate functions, designated
61
  *member candidates*, *non-member candidates*, *built-in candidates*, and
62
  *rewritten candidates*, are constructed as follows:
63
 
64
  - If `T1` is a complete class type or a class currently being defined,
65
- the set of member candidates is the result of the qualified lookup of
66
- `T1::operator@` [[over.call.func]]; otherwise, the set of member
67
- candidates is empty.
68
- - The set of non-member candidates is the result of the unqualified
69
- lookup of `operator@` in the context of the expression according to
70
- the usual rules for name lookup in unqualified function calls
71
- [[basic.lookup.argdep]] except that all member functions are ignored.
72
- However, if no operand has a class type, only those non-member
73
- functions in the lookup set that have a first parameter of type `T1`
74
- or “reference to cv `T1`”, when `T1` is an enumeration type, or (if
75
- there is a right operand) a second parameter of type `T2` or
76
  “reference to cv `T2`”, when `T2` is an enumeration type, are
77
  candidate functions.
78
  - For the operator `,`, the unary operator `&`, or the operator `->`,
79
  the built-in candidates set is empty. For all other operators, the
80
  built-in candidates include all of the candidate operator functions
@@ -82,32 +82,76 @@ operand of type *cv2* `T2`, four sets of candidate functions, designated
82
  - have the same operator name, and
83
  - accept the same number of operands, and
84
  - accept operand types to which the given operand or operands can be
85
  converted according to [[over.best.ics]], and
86
  - do not have the same parameter-type-list as any non-member candidate
87
- that is not a function template specialization.
 
88
  - The rewritten candidate set is determined as follows:
89
  - For the relational [[expr.rel]] operators, the rewritten candidates
90
  include all non-rewritten candidates for the expression `x <=> y`.
91
  - For the relational [[expr.rel]] and three-way comparison
92
  [[expr.spaceship]] operators, the rewritten candidates also include
93
  a synthesized candidate, with the order of the two parameters
94
  reversed, for each non-rewritten candidate for the expression
95
  `y <=> x`.
96
  - For the `!=` operator [[expr.eq]], the rewritten candidates include
97
- all non-rewritten candidates for the expression `x == y`.
 
98
  - For the equality operators, the rewritten candidates also include a
99
  synthesized candidate, with the order of the two parameters
100
  reversed, for each non-rewritten candidate for the expression
101
- `y == x`.
102
  - For all other operators, the rewritten candidate set is empty.
103
 
104
  \[*Note 2*: A candidate synthesized from a member candidate has its
105
- implicit object parameter as the second parameter, thus implicit
106
- conversions are considered for the first, but not for the second,
107
  parameter. — *end note*]
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  For the built-in assignment operators, conversions of the left operand
110
  are restricted as follows:
111
 
112
  - no temporaries are introduced to hold the left operand, and
113
  - no user-defined conversions are applied to the left operand to achieve
@@ -120,13 +164,13 @@ The set of candidate functions for overload resolution for some operator
120
  the built-in candidates, and the rewritten candidates for that operator
121
  `@`.
122
 
123
  The argument list contains all of the operands of the operator. The best
124
  function from the set of candidate functions is selected according to 
125
- [[over.match.viable]] and  [[over.match.best]].[^6]
126
 
127
- [*Example 2*:
128
 
129
  ``` cpp
130
  struct A {
131
  operator int();
132
  };
@@ -164,11 +208,11 @@ of the selected operation function, except that the second standard
164
  conversion sequence of a user-defined conversion sequence
165
  [[over.ics.user]] is not applied. Then the operator is treated as the
166
  corresponding built-in operator and interpreted according to
167
  [[expr.compound]].
168
 
169
- [*Example 3*:
170
 
171
  ``` cpp
172
  struct X {
173
  operator double();
174
  };
@@ -184,11 +228,11 @@ int *b = Y() + X(); // error: pointer arithmetic requires integral o
184
  — *end example*]
185
 
186
  The second operand of operator `->` is ignored in selecting an
187
  `operator->` function, and is not an argument when the `operator->`
188
  function is called. When `operator->` returns, the operator `->` is
189
- applied to the value returned, with the original second operand.[^7]
190
 
191
  If the operator is the operator `,`, the unary operator `&`, or the
192
  operator `->`, and there are no viable functions, then the operator is
193
  assumed to be the built-in operator and interpreted according to
194
  [[expr.compound]].
@@ -210,11 +254,11 @@ struct B {
210
 
211
  A a;
212
 
213
  void B::f() {
214
  operator+ (a,a); // error: global operator hidden by member
215
- a + a; // OK: calls global operator+
216
  }
217
  ```
218
 
219
  — *end note*]
220
 
 
30
  ```
31
 
32
  — *end example*]
33
 
34
  If either operand has a type that is a class or an enumeration, a
35
+ user-defined operator function can be declared that implements this
36
  operator or a user-defined conversion can be necessary to convert the
37
  operand to a type that is appropriate for a built-in operator. In this
38
  case, overload resolution is used to determine which operator function
39
  or built-in operator is to be invoked to implement the operator.
40
  Therefore, the operator notation is first transformed to the equivalent
 
60
  operand of type *cv2* `T2`, four sets of candidate functions, designated
61
  *member candidates*, *non-member candidates*, *built-in candidates*, and
62
  *rewritten candidates*, are constructed as follows:
63
 
64
  - If `T1` is a complete class type or a class currently being defined,
65
+ the set of member candidates is the result of a search for `operator@`
66
+ in the scope of `T1`; otherwise, the set of member candidates is
67
+ empty.
68
+ - For the operators `=`, `[]`, or `->`, the set of non-member candidates
69
+ is empty; otherwise, it includes the result of unqualified lookup for
70
+ `operator@` in the rewritten function call
71
+ [[basic.lookup.unqual]], [[basic.lookup.argdep]], ignoring all member
72
+ functions. However, if no operand has a class type, only those
73
+ non-member functions in the lookup set that have a first parameter of
74
+ type `T1` or “reference to cv `T1`”, when `T1` is an enumeration type,
75
+ or (if there is a right operand) a second parameter of type `T2` or
76
  “reference to cv `T2`”, when `T2` is an enumeration type, are
77
  candidate functions.
78
  - For the operator `,`, the unary operator `&`, or the operator `->`,
79
  the built-in candidates set is empty. For all other operators, the
80
  built-in candidates include all of the candidate operator functions
 
82
  - have the same operator name, and
83
  - accept the same number of operands, and
84
  - accept operand types to which the given operand or operands can be
85
  converted according to [[over.best.ics]], and
86
  - do not have the same parameter-type-list as any non-member candidate
87
+ or rewritten non-member candidate that is not a function template
88
+ specialization.
89
  - The rewritten candidate set is determined as follows:
90
  - For the relational [[expr.rel]] operators, the rewritten candidates
91
  include all non-rewritten candidates for the expression `x <=> y`.
92
  - For the relational [[expr.rel]] and three-way comparison
93
  [[expr.spaceship]] operators, the rewritten candidates also include
94
  a synthesized candidate, with the order of the two parameters
95
  reversed, for each non-rewritten candidate for the expression
96
  `y <=> x`.
97
  - For the `!=` operator [[expr.eq]], the rewritten candidates include
98
+ all non-rewritten candidates for the expression `x == y` that are
99
+ rewrite targets with first operand `x` (see below).
100
  - For the equality operators, the rewritten candidates also include a
101
  synthesized candidate, with the order of the two parameters
102
  reversed, for each non-rewritten candidate for the expression
103
+ `y == x` that is a rewrite target with first operand `y`.
104
  - For all other operators, the rewritten candidate set is empty.
105
 
106
  \[*Note 2*: A candidate synthesized from a member candidate has its
107
+ object parameter as the second parameter, thus implicit conversions
108
+ are considered for the first, but not for the second,
109
  parameter. — *end note*]
110
 
111
+ A non-template function or function template `F` named `operator==` is a
112
+ rewrite target with first operand `o` unless a search for the name
113
+ `operator!=` in the scope S from the instantiation context of the
114
+ operator expression finds a function or function template that would
115
+ correspond [[basic.scope.scope]] to `F` if its name were `operator==`,
116
+ where S is the scope of the class type of `o` if `F` is a class member,
117
+ and the namespace scope of which `F` is a member otherwise. A function
118
+ template specialization named `operator==` is a rewrite target if its
119
+ function template is a rewrite target.
120
+
121
+ [*Example 2*:
122
+
123
+ ``` cpp
124
+ struct A {};
125
+ template<typename T> bool operator==(A, T); // #1
126
+ bool a1 = 0 == A(); // OK, calls reversed #1
127
+ template<typename T> bool operator!=(A, T);
128
+ bool a2 = 0 == A(); // error, #1 is not a rewrite target
129
+
130
+ struct B {
131
+ bool operator==(const B&); // #2
132
+ };
133
+ struct C : B {
134
+ C();
135
+ C(B);
136
+ bool operator!=(const B&); // #3
137
+ };
138
+ bool c1 = B() == C(); // OK, calls #2; reversed #2 is not a candidate
139
+ // because search for operator!= in C finds #3
140
+ bool c2 = C() == B(); // error: ambiguous between #2 found when searching C and
141
+ // reversed #2 found when searching B
142
+
143
+ struct D {};
144
+ template<typename T> bool operator==(D, T); // #4
145
+ inline namespace N {
146
+ template<typename T> bool operator!=(D, T); // #5
147
+ }
148
+ bool d1 = 0 == D(); // OK, calls reversed #4; #5 does not forbid #4 as a rewrite target
149
+ ```
150
+
151
+ — *end example*]
152
+
153
  For the built-in assignment operators, conversions of the left operand
154
  are restricted as follows:
155
 
156
  - no temporaries are introduced to hold the left operand, and
157
  - no user-defined conversions are applied to the left operand to achieve
 
164
  the built-in candidates, and the rewritten candidates for that operator
165
  `@`.
166
 
167
  The argument list contains all of the operands of the operator. The best
168
  function from the set of candidate functions is selected according to 
169
+ [[over.match.viable]] and  [[over.match.best]].[^5]
170
 
171
+ [*Example 3*:
172
 
173
  ``` cpp
174
  struct A {
175
  operator int();
176
  };
 
208
  conversion sequence of a user-defined conversion sequence
209
  [[over.ics.user]] is not applied. Then the operator is treated as the
210
  corresponding built-in operator and interpreted according to
211
  [[expr.compound]].
212
 
213
+ [*Example 4*:
214
 
215
  ``` cpp
216
  struct X {
217
  operator double();
218
  };
 
228
  — *end example*]
229
 
230
  The second operand of operator `->` is ignored in selecting an
231
  `operator->` function, and is not an argument when the `operator->`
232
  function is called. When `operator->` returns, the operator `->` is
233
+ applied to the value returned, with the original second operand.[^6]
234
 
235
  If the operator is the operator `,`, the unary operator `&`, or the
236
  operator `->`, and there are no viable functions, then the operator is
237
  assumed to be the built-in operator and interpreted according to
238
  [[expr.compound]].
 
254
 
255
  A a;
256
 
257
  void B::f() {
258
  operator+ (a,a); // error: global operator hidden by member
259
+ a + a; // OK, calls global operator+
260
  }
261
  ```
262
 
263
  — *end note*]
264