operator overloading
Customizes the C++ operators for operands of user-defined types.
Syntax
Overloaded operators are functions with special function names:
1 | operator | op | | |
2 | operator | type | | |
3 | operator new operator new [] | |||
4 | operator delete operator delete [] | |||
5 | operator "" | suffix-identifier | (since C++11) | |
6 | operator co_await | (since C++20) | |
pub | op | any of the following operators: + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=> (since C++20) && || ++ -- , ->* -> ( ) [ ] |
- overloaded operator;
- user-defined conversion function;
- allocation function;
- deallocation function;
- user-defined literal;
- overloaded co_await operator for use in co_await expressions.
Overloaded operators
When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:
Expression | As member function | As non-member function | Example |
---|---|---|---|
@a | (a).operator@ ( ) | operator@ (a) | !std::cin
calls std::cin.operator!() |
a@b | (a).operator@ (b) | operator@ (a, b) | std::cout << 42
calls std::cout.operator<<(42) |
a=b | (a).operator= (b) | cannot be non-member | Given std::string s; ,
s = "abc";
calls s.operator=("abc") |
a(b...) | (a).operator()(b...) | cannot be non-member | Given std::random_device r; ,
auto n = r();
calls r.operator()() |
a[b...] | (a).operator | cannot be non-member | Given std::map<int, int> m; ,
m[1] = 2;
calls m.operator[](1) |
a-> | (a).operator-> ( ) | cannot be non-member | Given std::unique_ptr<S> p; ,
p->bar();
calls p.operator->() |
a@ | (a).operator@ (0) | operator@ (a, 0) | Given std::vector<int>::iterator i; ,
i++
calls i.operator++(0) |
In this table, @ is a placeholder representing all matching operators: all prefix operators in @a, all postfix operators other than -> in a@, all infix operators other than = in a@b. |
==
, !=
, <
, >
, <=
, >=
, <=>
,
overload resolution also considers the rewritten candidates generated from operator==
or operator<=>
. (since C++20)
Note: for overloading co_await (since C++20), user-defined conversion function, user-defined literals, allocation and deallocation see their respective articles.
Overloaded operators (but not the built-in operators) can be called using function notation:
std::string str = "Hello, ";
str.operator+=("world"); // same as str += "world";
operator<<(operator<<(std::cout, str), '\n'); // same as std::cout << str << '\n'
// (since C++17) except for sequencing
Restrictions
- The operators
::
(scope resolution),.
(member access),.*
(member access through pointer to member), and?:
(ternary conditional) cannot be overloaded. - New operators such as
**
,<>
, or&|
cannot be created. - It is not possible to change the precedence, grouping, or number of operands of operators.
- The overload of operator
->
must either return a raw pointer, or return an object (by reference or by value) for which operator->
is in turn overloaded. - The overloads of operators
&&
and||
lose short-circuit evaluation. -
&&
,||
, and,
(comma) lose their special sequencing properties when overloaded and behave like regular function calls even when they are used without function-call notation. (until C++17)