[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)
