The candidate operator functions that represent the built-in operators
defined in [expr.compound] are specified in this subclause.

These candidate
functions participate in the operator overload resolution process as
described in [over.match.oper] and are used for no other purpose.

[ Note

: *end note*

]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.

Also note that some of the candidate operator functions given in this subclause are
more permissive than the built-in operators themselves.

As
described in [over.match.oper], 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], and therefore to any
additional semantic constraints given there.

If there is a user-written
candidate with the same name and parameter types as a built-in
candidate operator function, the built-in operator function
is hidden and is not included in the set of candidate functions.

— In this subclause, the term
*promoted integral type*
is used to refer to those integral types which are preserved by
integral promotion (including e.g.
int
and
long
but excluding e.g.
char).

Similarly, the term
*promoted arithmetic type*
refers to floating-point types plus promoted integral types.

For every pair
(T,
vq),
where
T
is an arithmetic type other than bool,
there exist candidate operator functions of the form

vq T& operator++(vq T&); T operator++(vq T&, int);

For every pair
(T,
vq),
where
T
is an arithmetic type other than
bool,
there exist candidate operator functions of the form

vq T& operator--(vq T&); T operator--(vq T&, int);

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&); T*vq& operator--(T*vq&); T* operator++(T*vq&, int); T* operator--(T*vq&, int);

For every cv-qualified or cv-unqualified object type
T,
there exist candidate operator functions of the form

T& operator*(T*);

For every function type
T that does not have cv-qualifiers or a *ref-qualifier*,
there exist candidate operator functions of the form

T& operator*(T*);

For every promoted arithmetic type
T,
there exist candidate operator functions of the form

T operator+(T); T operator-(T);

For every promoted integral type
T,
there exist candidate operator functions of the form

T operator~(T);

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::*);

The return type is shown for exposition only; see [expr.mptr.oper] for the
determination of the operator's result type.

For every pair of promoted arithmetic 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); 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]) between types
L
and
R.

For every integral type T
there exists a candidate operator function of the form

std::strong_ordering operator<=>(T, T);

For every pair of floating-point types
L and R,
there exists a candidate operator function of the form

std::partial_ordering operator<=>(L, R);

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*);

For every
T,
where
T
is a pointer to object type,
there exist candidate operator functions of the form

std::ptrdiff_t operator-(T, T);

For every T, where T is an enumeration type or a pointer type,
there exist candidate operator functions of the form

bool 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);

For every T, where T
is a pointer-to-member type or std::nullptr_t,
there exist candidate operator functions of the form

bool operator==(T, T); bool operator!=(T, T); std::strong_equality operator<=>(T, T);

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]) between types L and R.

For every triple
(L,
vq,
R),
where
L
is an arithmetic type,
and
R
is a promoted arithmetic 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);

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

T*vq& operator=(T*vq&, T*);

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

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

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

There also exist candidate operator functions of the form

bool operator!(bool); bool operator&&(bool, bool); bool operator||(bool, bool);

For every pair of promoted arithmetic types
L
and
R,
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]) between types L and R.