Increment/decrement operators
inline
specifier noexcept
specifier (C++11)typedef
declaration Increment/decrement operators increment or decrement the value of the object.
Operator name | Syntax | Overloadable | Prototype examples (for class T) | |
---|---|---|---|---|
Inside class definition | Outside class definition | |||
pre-increment | ++a
|
Yes | T& T::operator++(); | T& operator++(T& a); |
pre-decrement | --a
|
Yes | T& T::operator--(); | T& operator--(T& a); |
post-increment | a++
|
Yes | T T::operator++(int); | T operator++(T& a, int); |
post-decrement | a--
|
Yes | T T::operator--(int); | T operator--(T& a, int); |
|
Contents
[edit] Prefix operators
The prefix increment and decrement expressions have the form
++
expression
--
expression
[edit] Built-in prefix operators
- If the type of expression is (possibly volatile-qualified) bool, expression is set to true. Such a increment is deprecated.
- If the type of expression is (possibly cv-qualified) bool, the program is ill-formed.
- If the type of expression is volatile-qualified, the increment is deprecated.
- If the type of expression is (possibly cv-qualified) bool, the program is ill-formed.
- If the type of expression is volatile-qualified, the decrement is deprecated.
[edit] Overloads
In overload resolution against user-defined operators, for every optionally volatile-qualified arithmetic type A
other than bool, and for every optionally volatile-qualified pointer P
to optionally cv-qualified object type, the following function signatures participate in overload resolution:
[edit] Postfix operators
The postfix increment and decrement expressions have the form
++
--
[edit] Built-in postfix operators
The result of postfix increment or decrement is the value obtained by applying the lvalue-to-rvalue conversion to expression (before modification). The type of the result is the cv-unqualified version of the type of expression.
If expression is not a modifiable lvalue of an arithmetic type other than (possibly cv-qualified) bool(since C++17), or a pointer to a complete object type, the program is ill-formed.
If the type of expression is volatile-qualified, the increment or decrement is deprecated.
(since C++20)++
operator.--
operator.The value computation of a postfix increment or decrement is sequenced before the modification of expression. With respect to an indeterminately-sequenced function call, the operation of a postfix increment or decrement is a single evaluation.
[edit] Overloads
In overload resolution against user-defined operators, for every optionally volatile-qualified arithmetic type A
other than bool, and for every optionally volatile-qualified pointer P
to optionally cv-qualified object type, the following function signatures participate in overload resolution:
[edit] Example
#include <iostream> int main() { int n1 = 1; int n2 = ++n1; int n3 = ++ ++n1; int n4 = n1++; // int n5 = n1++ ++; // error // int n6 = n1 + ++n1; // undefined behavior std::cout << "n1 = " << n1 << '\n' << "n2 = " << n2 << '\n' << "n3 = " << n3 << '\n' << "n4 = " << n4 << '\n'; }
Output:
n1 = 5 n2 = 2 n3 = 4 n4 = 4
[edit] Notes
Because of the side-effects involved, built-in increment and decrement operators must be used with care to avoid undefined behavior due to violations of sequencing rules.
Because a temporary copy of the object is constructed during post-increment and post-decrement, pre-increment or pre-decrement operators are usually more efficient in contexts where the returned value is not used.
[edit] Standard library
Increment and decrement operators are overloaded for many standard library types. In particular, every LegacyIterator overloads operator++ and every LegacyBidirectionalIterator overloads operator--, even if those operators are no-ops for the particular iterator.
overloads for arithmetic types
(public member function of
std::chrono::duration<Rep,Period>
) [edit]
overloads for iterator types
reverse_iterator
(public member function of
std::reverse_iterator<Iter>
) [edit]
move_iterator
(public member function of
std::move_iterator<Iter>
) [edit]
(public member function of
std::istream_iterator<T,CharT,Traits,Distance>
) [edit]
(public member function of
std::regex_iterator<BidirIt,CharT,Traits>
) [edit]
(public member function of
std::regex_token_iterator<BidirIt,CharT,Traits>
) [edit]
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 2855 | C++98 | usual arithmetic conversions are applied for built-in pre-increment and pre-decrement, but were not applied for their postfix counterparts[1] |
also applied |
CWG 2901 | C++98 | lvalue-to-rvalue conversions were not applied for built-in post-increment and post-decrement |
applied |
- ↑ The prefix ++x is equivalent to x += 1, and the latter is applicable for usual arithmetic conversions (i.e. yield a common type between decltype(x) and int). However, the effect of the postfix x++ is simply "adding one to x", there is no binary operator present, so no usual arithmetic conversions will take place.
[edit] See also
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement |
arithmetic | logical | comparison | member access |
other |
a = b |
++a |
+a |
!a |
a == b |
a[...] |
function call a(...) |
comma a, b | ||||||
conditional a ? b : c | ||||||
Special operators | ||||||
static_cast converts one type to another related type |