332 lines
15 KiB
Markdown
332 lines
15 KiB
Markdown
[over.match.oper]
|
||
|
||
# 12 Overloading [[over]](./#over)
|
||
|
||
## 12.2 Overload resolution [[over.match]](over.match#oper)
|
||
|
||
### 12.2.2 Candidate functions and argument lists [[over.match.funcs]](over.match.funcs#over.match.oper)
|
||
|
||
#### 12.2.2.3 Operators in expressions [over.match.oper]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L661)
|
||
|
||
If no operand of an operator in an expression has a type that is a class
|
||
or an enumeration, the operator is assumed to be a built-in operator
|
||
and interpreted according to [[expr.compound]](expr.compound "7.6 Compound expressions")[.](#1.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Because.,.*,
|
||
and:: cannot be overloaded,
|
||
these operators are always built-in operators interpreted according to[[expr.compound]](expr.compound "7.6 Compound expressions")[.](#1.sentence-2)
|
||
|
||
?: cannot be overloaded, but the rules in this subclause are used to determine
|
||
the conversions to be applied to the second and third operands when they
|
||
have class or enumeration type ([[expr.cond]](expr.cond "7.6.16 Conditional operator"))[.](#1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#example-1)*: struct String { String (const String&);
|
||
String (const char*); operator const char* ();};
|
||
String operator + (const String&, const String&);
|
||
|
||
void f() {const char* p= "one" + "two"; // error: cannot add two pointers; overloaded operator+ not considered// because neither operand has class or enumeration typeint I = 1 + 1; // always evaluates to 2 even if class or enumeration types exist// that would perform the operation.} â *end example*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L697)
|
||
|
||
If either operand has a type that is a class or an enumeration, a
|
||
user-defined operator function can be declared that implements
|
||
this operator or a user-defined conversion can be necessary to
|
||
convert the operand to a type that is appropriate for a built-in
|
||
operator[.](#2.sentence-1)
|
||
|
||
In this case, overload resolution is used to determine
|
||
which operator function or built-in operator is to be invoked to implement the
|
||
operator[.](#2.sentence-2)
|
||
|
||
Therefore, the operator notation is first transformed
|
||
to the equivalent function-call notation as summarized in
|
||
Table [18](#tab:over.match.oper "Table 18: Relationship between operator and function call notation") (where @ denotes one of the operators covered in the specified subclause)[.](#2.sentence-3)
|
||
|
||
However, the operands are sequenced in the order prescribed
|
||
for the built-in operator ([[expr.compound]](expr.compound "7.6 Compound expressions"))[.](#2.sentence-4)
|
||
|
||
Table [18](#tab:over.match.oper) — Relationship between operator and function call notation [[tab:over.match.oper]](./tab:over.match.oper)
|
||
|
||
| [ð](#tab:over.match.oper-row-1)<br>**Subclause** | **Expression** | **As member function** | **As non-member function** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:over.match.oper-row-2)<br>[[over.unary]](over.unary "12.4.2 Unary operators") | @a | (a).operator@ ( ) | operator@(a) |
|
||
| [ð](#tab:over.match.oper-row-3)<br>[[over.binary]](over.binary "12.4.3 Binary operators") | a@b | (a).operator@ (b) | operator@(a, b) |
|
||
| [ð](#tab:over.match.oper-row-4)<br>[[over.assign]](over.assign "12.4.3.2 Simple assignment") | a=b | (a).operator= (b) | |
|
||
| [ð](#tab:over.match.oper-row-5)<br>[[over.sub]](over.sub "12.4.5 Subscripting") | a[b] | (a).operator[](b) | |
|
||
| [ð](#tab:over.match.oper-row-6)<br>[[over.ref]](over.ref "12.4.6 Class member access") | a-> | (a).operator->( ) | |
|
||
| [ð](#tab:over.match.oper-row-7)<br>[[over.inc]](over.inc "12.4.7 Increment and decrement") | a@ | (a).operator@ (0) | operator@(a, 0) |
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L725)
|
||
|
||
For a unary operator @ with an operand of type *cv1* T1,
|
||
and for a binary operator @ with a left operand of type *cv1* T1 and a right operand of type *cv2* T2,
|
||
four sets of candidate functions, designated[*member candidates*](#def:member_candidate "12.2.2.3 Operators in expressions [over.match.oper]"),[*non-member candidates*](#def:non-member_candidate "12.2.2.3 Operators in expressions [over.match.oper]"),[*built-in candidates*](#def:built-in_candidate "12.2.2.3 Operators in expressions [over.match.oper]"),
|
||
and[*rewritten candidates*](#def:rewritten_candidate "12.2.2.3 Operators in expressions [over.match.oper]"),
|
||
are constructed as follows:
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
If T1 is a complete class type or a class currently being defined,
|
||
the set of member candidates is the result of a search foroperator@ in the scope of T1;
|
||
otherwise, the set of member candidates is empty[.](#3.1.sentence-1)
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
For the operators =, [], or ->,
|
||
the set of non-member candidates is empty;
|
||
otherwise, it includes the result of unqualified lookup foroperator@ in the rewritten function call ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"), [[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup")),
|
||
ignoring all member functions[.](#3.2.sentence-1)
|
||
However, if no operand has a class type, only those non-member
|
||
functions in the lookup set that have a first parameter of typeT1 or âreference to cv T1â,
|
||
whenT1 is an enumeration type,
|
||
or (if there is a right operand) a second parameter of typeT2 or âreference to cv T2â,
|
||
whenT2 is an enumeration type,
|
||
are candidate functions[.](#3.2.sentence-2)
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
For the operator,,
|
||
the unary operator&,
|
||
or the operator->,
|
||
the built-in candidates set is empty[.](#3.3.sentence-1)
|
||
For all other operators, the built-in candidates include all
|
||
of the candidate operator functions defined in [[over.built]](over.built "12.5 Built-in operators") that,
|
||
compared to the given operator,
|
||
* [(3.3.1)](#3.3.1)
|
||
|
||
have the same operator name, and
|
||
|
||
* [(3.3.2)](#3.3.2)
|
||
|
||
accept the same number of operands, and
|
||
|
||
* [(3.3.3)](#3.3.3)
|
||
|
||
accept operand types to which the given operand or
|
||
operands can be converted according to [[over.best.ics]](over.best.ics "12.2.4.2 Implicit conversion sequences"), and
|
||
|
||
* [(3.3.4)](#3.3.4)
|
||
|
||
do not have the same parameter-type-list as any non-member candidate
|
||
or rewritten non-member candidate
|
||
that is not a function template specialization[.](#3.3.sentence-2)
|
||
|
||
- [(3.4)](#3.4)
|
||
|
||
The rewritten candidate set is determined as follows:
|
||
* [(3.4.1)](#3.4.1)
|
||
|
||
For the relational ([[expr.rel]](expr.rel "7.6.9 Relational operators")) operators,
|
||
the rewritten candidates include
|
||
all non-rewritten candidates
|
||
for the expression x <=> y[.](#3.4.1.sentence-1)
|
||
|
||
* [(3.4.2)](#3.4.2)
|
||
|
||
For the
|
||
relational ([[expr.rel]](expr.rel "7.6.9 Relational operators")) and
|
||
three-way comparison ([[expr.spaceship]](expr.spaceship "7.6.8 Three-way comparison operator"))
|
||
operators,
|
||
the rewritten candidates also include
|
||
a synthesized candidate,
|
||
with the order of the two parameters reversed,
|
||
for each non-rewritten candidate
|
||
for the expressiony <=> x[.](#3.4.2.sentence-1)
|
||
|
||
* [(3.4.3)](#3.4.3)
|
||
|
||
For the != operator ([[expr.eq]](expr.eq "7.6.10 Equality operators")),
|
||
the rewritten candidates
|
||
include all non-rewritten candidates
|
||
for the expression x == y that are rewrite targets with first operand x (see below)[.](#3.4.3.sentence-1)
|
||
|
||
* [(3.4.4)](#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 that is a rewrite target with first operand y[.](#3.4.4.sentence-1)
|
||
|
||
* [(3.4.5)](#3.4.5)
|
||
|
||
For all other operators, the rewritten candidate set is empty[.](#3.4.5.sentence-1)
|
||
|
||
[*Note [2](#note-2)*:
|
||
A candidate synthesized from a member candidate has its
|
||
object parameter as the second parameter, thus implicit conversions
|
||
are considered for the first, but not for the second, parameter[.](#3.4.sentence-2)
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L832)
|
||
|
||
A non-template function or function template F named operator== is a rewrite target with first operand o unless a search for the name operator!= in the scope S from the instantiation context of the operator expression
|
||
finds a function or function template
|
||
that would correspond ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")) to F if its name were operator==,
|
||
where S is the scope of the class type of o if F is a class member, and
|
||
the namespace scope of which F is a member otherwise[.](#4.sentence-1)
|
||
|
||
A function template specialization named operator== is a rewrite target
|
||
if its function template is a rewrite target[.](#4.sentence-2)
|
||
|
||
[*Example [2](#example-2)*: struct A {};template<typename T> bool operator==(A, T); // #1bool a1 = 0 == A(); // OK, calls reversed #1template<typename T> bool operator!=(A, T);bool a2 = 0 == A(); // error, #1 is not a rewrite targetstruct B {bool operator==(const B&); // #2};struct C : B { C();
|
||
C(B); bool operator!=(const B&); // #3};bool c1 = B() == C(); // OK, calls #2; reversed #2 is not a candidate// because search for operator!= in C finds #3bool c2 = C() == B(); // error: ambiguous between #2 found when searching C and// reversed #2 found when searching Bstruct D {};template<typename T> bool operator==(D, T); // #4inline namespace N {template<typename T> bool operator!=(D, T); // #5}bool d1 = 0 == D(); // OK, calls reversed #4; #5 does not forbid #4 as a rewrite target â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L875)
|
||
|
||
For the first parameter of the built-in assignment operators,
|
||
only standard conversion sequences ([[over.ics.scs]](over.ics.scs "12.2.4.2.2 Standard conversion sequences")) are considered[.](#5.sentence-1)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L879)
|
||
|
||
For all other operators, no such restrictions apply[.](#6.sentence-1)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L882)
|
||
|
||
The set of candidate functions for overload resolution
|
||
for some operator @ is the
|
||
union of
|
||
the member candidates,
|
||
the non-member candidates,
|
||
the built-in candidates,
|
||
and the rewritten candidates
|
||
for that operator @[.](#7.sentence-1)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L893)
|
||
|
||
The argument list contains all of the
|
||
operands of the operator[.](#8.sentence-1)
|
||
|
||
The best function from the set of candidate functions is selected
|
||
according to [[over.match.viable]](over.match.viable "12.2.3 Viable functions") and [[over.match.best]](over.match.best "12.2.4 Best viable function")[.](#8.sentence-2)[103](#footnote-103 "If the set of candidate functions is empty, overload resolution is unsuccessful.")
|
||
|
||
[*Example [3](#example-3)*: struct A {operator int();};
|
||
A operator+(const A&, const A&);void m() { A a, b;
|
||
a + b; // operator+(a, b) chosen over int(a) + int(b)} â *end example*]
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L916)
|
||
|
||
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 rewritten operator<=> candidate[.](#9.sentence-1)
|
||
|
||
Rewritten candidates for the operator @ are not considered in the context of the resulting expression[.](#9.sentence-2)
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L930)
|
||
|
||
If a rewritten operator== candidate
|
||
is selected by overload resolution
|
||
for an operator @,
|
||
its return type shall be cv bool, andx @ y is interpreted as:
|
||
|
||
- [(10.1)](#10.1)
|
||
|
||
if @ is != and the selected candidate is a synthesized candidate
|
||
with reversed order of parameters,!(y == x),
|
||
|
||
- [(10.2)](#10.2)
|
||
|
||
otherwise, if @ is !=,!(x == y),
|
||
|
||
- [(10.3)](#10.3)
|
||
|
||
otherwise (when @ is ==),y == x,
|
||
|
||
in each case using the selected rewritten operator== candidate[.](#10.sentence-1)
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L951)
|
||
|
||
If a built-in candidate is selected by overload resolution, the
|
||
operands of class type are converted to the types of the corresponding parameters
|
||
of the selected operation function, except that the second standard conversion
|
||
sequence of a [user-defined conversion sequence](over.ics.user "12.2.4.2.3 User-defined conversion sequences [over.ics.user]") is not applied[.](#11.sentence-1)
|
||
|
||
Then the operator is treated as the corresponding
|
||
built-in operator and interpreted according to [[expr.compound]](expr.compound "7.6 Compound expressions")[.](#11.sentence-2)
|
||
|
||
[*Example [4](#example-4)*: struct X {operator double();};
|
||
|
||
struct Y {operator int*();};
|
||
|
||
int *a = Y() + 100.0; // error: pointer arithmetic requires integral operandint *b = Y() + X(); // error: pointer arithmetic requires integral operand â *end example*]
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L973)
|
||
|
||
The second operand of operator-> is ignored in selecting anoperator-> function, and is not an argument when theoperator-> function is called[.](#12.sentence-1)
|
||
|
||
Whenoperator-> returns, the operator-> is applied to the value returned, with the original second
|
||
operand[.](#12.sentence-2)[104](#footnote-104 "If the value returned by the operator-> function has class type, this can result in selecting and calling another operator-> function. The process repeats until an operator-> function returns a value of non-class type.")
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L998)
|
||
|
||
If the operator is the operator,,
|
||
the unary operator&,
|
||
or the operator->,
|
||
and there are no viable functions, then the operator is
|
||
assumed to be the built-in operator and interpreted according to[[expr.compound]](expr.compound "7.6 Compound expressions")[.](#13.sentence-1)
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1009)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
The lookup rules for operators in expressions are different than
|
||
the lookup
|
||
rules for operator function names in a function call, as shown in the following
|
||
example:struct A { };void operator + (A, A);
|
||
|
||
struct B {void operator + (B); void f ();};
|
||
|
||
A a;
|
||
|
||
void B::f() {operator+ (a,a); // error: global operator hidden by member a + a; // OK, calls global operator+}
|
||
|
||
â *end note*]
|
||
|
||
[103)](#footnote-103)[103)](#footnoteref-103)
|
||
|
||
If the set of candidate functions is empty,
|
||
overload resolution is unsuccessful[.](#footnote-103.sentence-1)
|
||
|
||
[104)](#footnote-104)[104)](#footnoteref-104)
|
||
|
||
If the value returned by theoperator-> function has class type, this can result in selecting and calling anotheroperator-> function[.](#footnote-104.sentence-1)
|
||
|
||
The process repeats until anoperator-> function returns a value of non-class type[.](#footnote-104.sentence-2)
|