[over.built]

# 12 Overloading [[over]](./#over)

## 12.5 Built-in operators [over.built]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3775)

The candidate operator functions that represent the built-in operators
defined in [[expr.compound]](expr.compound "7.6 Compound expressions") are specified in this subclause[.](#1.sentence-1)

These candidate
functions participate in the operator overload resolution process as
described in [[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions") and are used for no other purpose[.](#1.sentence-2)

[*Note [1](#note-1)*:

Because built-in operators take only operands with non-class type,
and operator overload resolution occurs only when an operand expression
originally has class or enumeration type,
operator overload resolution can resolve to a built-in operator only
when an operand has a class type that has a user-defined conversion to
a non-class type appropriate for the operator, or when an operand has
an enumeration type that can be converted to a type appropriate
for the operator[.](#1.sentence-3)

Also note that some of the candidate operator functions given in this subclause are
more permissive than the built-in operators themselves[.](#1.sentence-4)

As
described in [[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"), after a built-in operator is selected
by overload resolution the expression is subject to the requirements for
the built-in operator given in [[expr.compound]](expr.compound "7.6 Compound expressions"), and therefore to any
additional semantic constraints given there[.](#1.sentence-5)

In some cases, user-written candidates
with the same name and parameter types as a built-in
candidate operator function cause the built-in operator function
to not be included in the set of candidate functions[.](#1.sentence-6)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3803)

In this subclause, the term[*promoted integral type*](#def:promoted_integral_type "12.5 Built-in operators [over.built]") is used to refer to those cv-unqualified integral types which are preserved by[integral promotion](conv.prom "7.3.7 Integral promotions [conv.prom]") (including e.g.int andlong but excluding e.g.char)[.](#2.sentence-1)

[*Note [2](#note-2)*:

In all cases where a promoted integral type is
required, an operand of unscoped enumeration type will be acceptable by way of the
integral promotions[.](#2.sentence-2)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3821)

In the remainder of this subclause, *vq* represents eithervolatile or no cv-qualifier[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3825)

For every pair
(*T*,*vq*),
where*T* is a cv-unqualified arithmetic type other than bool or a cv-unqualified pointer to (possibly cv-qualified) object type,
there exist candidate operator functions of the form*vq* *T*& operator++(*vq* *T*&);*T* operator++(*vq* *T*&, int);*vq* *T*& operator--(*vq* *T*&);*T* operator--(*vq* *T*&, int);

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3841)

For every (possibly cv-qualified) object type *T* and
for every function type *T* that has neither [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* nor a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]"),
there exist candidate operator functions of the form*T*& operator*(*T**);

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3850)

For every type *T* there exist candidate operator functions of the form*T** operator+(*T**);

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3856)

For every cv-unqualified floating-point or promoted integral type *T*,
there exist candidate operator functions of the form*T* operator+(*T*);*T* operator-(*T*);

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3864)

For every promoted integral type*T*,
there exist candidate operator functions of the form*T* operator~(*T*);

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3872)

For every quintuple
(*C1*,*C2*,*T*,*cv1*,*cv2*),
where*C2* is a class type,*C1* is the same type as *C2* or is a derived class of *C2*, and*T* is an object type or a function type,
there exist candidate operator functions of the form*cv12* *T*& operator->*(*cv1* *C1**, *cv2* *T C2*::*); where *cv12* is the union of *cv1* and *cv2*[.](#9.sentence-1)

The return type is shown for exposition only; see [[expr.mptr.oper]](expr.mptr.oper "7.6.4 Pointer-to-member operators") for the
determination of the operator's result type[.](#9.sentence-2)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3894)

For every pair of types *L* and *R*,
where each of *L* and *R* is a
floating-point or promoted integral type,
there exist candidate operator functions of the form*LR* operator*(*L*, *R*);*LR* operator/(*L*, *R*);*LR* operator+(*L*, *R*);*LR* operator-(*L*, *R*);bool operator==(*L*, *R*);bool operator!=(*L*, *R*);bool operator<(*L*, *R*);bool operator>(*L*, *R*);bool operator<=(*L*, *R*);bool operator>=(*L*, *R*); where*LR* is the result of the usual arithmetic conversions ([[expr.arith.conv]](expr.arith.conv "7.4 Usual arithmetic conversions")) between types*L* and*R*[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3918)

For every integral type *T* there exists a candidate operator function of the formstd::strong_ordering operator<=>(*T*, *T*);

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3925)

For every pair of floating-point types*L* and *R*,
there exists a candidate operator function of the formstd::partial_ordering operator<=>(*L*, *R*);

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3933)

For every cv-qualified or cv-unqualified object type*T* there exist candidate operator functions of the form*T** operator+(*T**, std::ptrdiff_t);*T*& operator[](*T**, std::ptrdiff_t);*T** operator-(*T**, std::ptrdiff_t);*T** operator+(std::ptrdiff_t, *T**);*T*& operator[](std::ptrdiff_t, *T**);

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3945)

For every*T*,
where*T* is a pointer to object type,
there exist candidate operator functions of the formstd::ptrdiff_t operator-(*T*, *T*);

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3956)

For every *T*, where *T* is an enumeration type or a pointer type,
there exist candidate operator functions of the formbool operator==(*T*, *T*);bool operator!=(*T*, *T*);bool operator<(*T*, *T*);bool operator>(*T*, *T*);bool operator<=(*T*, *T*);bool operator>=(*T*, *T*);*R* operator<=>(*T*, *T*); where *R* is the result type specified in [[expr.spaceship]](expr.spaceship "7.6.8 Three-way comparison operator")[.](#15.sentence-1)

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3970)

For every *T*, where *T* is a pointer-to-member type, std​::​meta​::​info, or std​::​nullptr_t,
there exist candidate operator functions of the formbool operator==(*T*, *T*);bool operator!=(*T*, *T*);

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3979)

For every pair of promoted integral types*L* and*R*,
there exist candidate operator functions of the form*LR* operator%(*L*, *R*);*LR* operator&(*L*, *R*);*LR* operator^(*L*, *R*);*LR* operator|(*L*, *R*);*L* operator<<(*L*, *R*);*L* operator>>(*L*, *R*); where*LR* is the result of the usual arithmetic conversions ([[expr.arith.conv]](expr.arith.conv "7.4 Usual arithmetic conversions")) between types*L* and*R*[.](#17.sentence-1)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4000)

For every triple
(*L*, *vq*, *R*),
where *L* is an arithmetic type,
and *R* is a floating-point or promoted integral type,
there exist candidate operator functions of the form*vq* *L*& operator=(*vq* *L*&, *R*);*vq* *L*& operator*=(*vq* *L*&, *R*);*vq* *L*& operator/=(*vq* *L*&, *R*);*vq* *L*& operator+=(*vq* *L*&, *R*);*vq* *L*& operator-=(*vq* *L*&, *R*);

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4014)

For every pair (*T*, *vq*),
where *T* is any type,
there exist candidate operator functions of the form*T***vq*& operator=(*T***vq*&, *T**);

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4022)

For every pair
(*T*,*vq*),
where*T* is an enumeration or pointer-to-member type,
there exist candidate operator functions of the form*vq* *T*& operator=(*vq* *T*&, *T*);

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4034)

For every pair
(*T*,*vq*),
where*T* is a cv-qualified or cv-unqualified object type,
there exist candidate operator functions of the form*T***vq*& operator+=(*T***vq*&, std::ptrdiff_t);*T***vq*& operator-=(*T***vq*&, std::ptrdiff_t);

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4047)

For every triple
(*L*,*vq*,*R*),
where*L* is an integral type, and*R* is a promoted integral type,
there exist candidate operator functions of the form*vq* *L*& operator%=(*vq* *L*&, *R*);*vq* *L*& operator<<=(*vq* *L*&, *R*);*vq* *L*& operator>>=(*vq* *L*&, *R*);*vq* *L*& operator&=(*vq* *L*&, *R*);*vq* *L*& operator^=(*vq* *L*&, *R*);*vq* *L*& operator|=(*vq* *L*&, *R*);

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4067)

There also exist candidate operator functions of the formbool operator!(bool);bool operator&&(bool, bool);bool operator||(bool, bool);

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4075)

For every pair of types *L* and *R*,
where each of *L* and *R* is a
floating-point or promoted integral type,
there exist candidate operator functions of the form*LR* operator?:(bool, *L*, *R*); where*LR* is the result of the usual arithmetic conversions ([[expr.arith.conv]](expr.arith.conv "7.4 Usual arithmetic conversions")) between types*L* and*R*[.](#24.sentence-1)

[*Note [3](#note-3)*:

As with all these descriptions of candidate functions, this declaration serves
only to describe the built-in operator for purposes of overload resolution[.](#24.sentence-2)

The operator
â?:â
cannot be overloaded[.](#24.sentence-3)

â *end note*]

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L4097)

For every type*T*,
where*T* is a pointer, pointer-to-member, or scoped enumeration type, there exist candidate operator
functions of the form*T* operator?:(bool, *T*, *T*);
