13 Overloading [over]

13.6 Built-in operators [over.built]

The candidate operator functions that represent the built-in operators defined in Clause [expr] 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: 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 Clause [expr], 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.  — end note ]

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 types plus promoted integral types. [ Note: In all cases where a promoted integral type or promoted arithmetic type is required, an operand of enumeration type will be acceptable by way of the integral promotions.  — end note ]

For every pair (T, VQ), where T is an arithmetic type other than bool, and VQ is either volatile or empty, 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, and VQ is either volatile or empty, 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, and VQ is either volatile or empty, 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 type T 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, T is an object type or a function type, and CV1 and CV2 are cv-qualifier-seqs, 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. 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 between types L and 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);

For every pointer to member type T or type std::nullptr_t there exist candidate operator functions of the form

bool    operator==(T, T);
bool    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 between types L and R.

For every triple (L, VQ, R), where L is an arithmetic type, VQ is either volatile or empty, 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 and VQ is either volatile or empty, 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 and VQ is either volatile or empty, 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 and VQ is either volatile or empty, 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, VQ is either volatile or empty, 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 between types L and R. [ Note: As with all these descriptions of candidate functions, this declaration serves only to describe the built-in operator for purposes of overload resolution. The operator “?:” cannot be overloaded.  — end note ]

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