Increment/decrement operators - cppreference.com (original) (raw)
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); |
| Notes Prefix versions of the built-in operators return references and postfix versions return values, and typical user-defined overloads follow the pattern so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void). The int parameter is a dummy parameter used to differentiate between prefix and postfix versions of the operators. When the user-defined postfix operator is called, the value passed in that parameter is always zero, although it may be changed by calling the operator using function call notation (e.g., a.operator++(2) or operator++(a, 2)). |
Contents
[edit] Prefix operators
The prefix increment and decrement expressions have the form
| | | | | ------------------ | | | | ++ expression | | | | | | | | -- expression | | | | | | |
prefix increment (pre-increment)
prefix decrement (pre-decrement)
[edit] Built-in prefix operators
- The expression ++x is equivalent to x += 1, with the following exceptions:
| If the type of expression is (possibly volatile-qualified) bool, expression is set to true. Such a increment is deprecated. | (until C++17) |
|---|---|
| If the type of expression is (possibly cv-qualified) bool, the program is ill-formed. | (since C++17) |
| If the type of expression is volatile-qualified, the increment is deprecated. | (since C++20) |
- The expression --x is equivalent to x -= 1, with the following exceptions:
- 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. | (since C++20) |
|---|
[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:
| A& operator++(A&) | | | | ----------------------- | | ------------------------- | | bool& operator++(bool&) | | (deprecated)(until C++17) | | P& operator++(P&) | | | | A& operator--(A&) | | | | P& operator--(P&) | | |
[edit] Postfix operators
The postfix increment and decrement expressions have the form
| | | | | ------------------ | | | | expression ++ | | | | | | | | expression -- | | | | | | |
postfix increment (post-increment)
postfix decrement (post-decrement)
[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) |
|---|
The value of expression is modified as if it were the operand of the prefix
++operator.The value of expression is modified as if it were the operand of the prefix
--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:
| A operator++(A&, int) | | | | --------------------------- | | ------------------------- | | bool operator++(bool&, int) | | (deprecated)(until C++17) | | P operator++(P&, int) | | | | A operator--(A&, int) | | | | P operator--(P&, int) | | |
[edit] Example
#include 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 | |
|---|---|
| operator++operator++(int)operator--operator--(int) | increments or decrements the atomic value by one (public member function of std::atomic) [edit] |
| operator++operator++(int)operator--operator--(int) | increments or decrements the tick count (public member function of std::chrono::duration<Rep,Period>) [edit] |
| overloads for iterator types | |
| operator++operator++(int) | advances the iterator (public member function of std::raw_storage_iterator<OutputIt,T>) [edit] |
| operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator- | advances or decrements the reverse_iterator (public member function of std::reverse_iterator) [edit] |
| operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator- | advances or decrements the move_iterator (public member function of std::move_iterator) [edit] |
| operator++operator++(int) | no-op (public member function of std::front_insert_iterator) [edit] |
| operator++operator++(int) | no-op (public member function of std::back_insert_iterator) [edit] |
| operator++operator++(int) | no-op (public member function of std::insert_iterator) [edit] |
| operator++operator++(int) | advances the iterator (public member function of std::istream_iterator<T,CharT,Traits,Distance>) [edit] |
| operator++operator++(int) | no-op (public member function of std::ostream_iterator<T,CharT,Traits>) [edit] |
| operator++operator++(int) | advances the iterator (public member function of std::istreambuf_iterator<CharT,Traits>) [edit] |
| operator++operator++(int) | no-op (public member function of std::ostreambuf_iterator<CharT,Traits>) [edit] |
| operator++operator++(int) | advances the iterator to the next match (public member function of std::regex_iterator<BidirIt,CharT,Traits>) [edit] |
| operator++operator++(int) | advances the iterator to the next submatch (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 andpre-decrement, but were not applied for their postfix counterparts[1] | also applied |
| CWG 2901 | C++98 | lvalue-to-rvalue conversions were not appliedfor 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 | incrementdecrement | arithmetic | logical | comparison | member access | other |
| a = ba += ba -= ba *= ba /= ba %= ba &= ba |= ba ^= ba <<= ba >>= b | ++a --aa++a-- | +a -aa + ba - ba * ba / ba % b~aa & ba | ba ^ ba << ba >> b | !aa && ba | | b | a == ba != ba < ba > ba <= ba >= ba <=> b | a[...] *a &aa->ba.ba->*ba.*b |
| commaa, b | ||||||
| conditionala ? b : c | ||||||
| Special operators | ||||||
| static_cast converts one type to another related type dynamic_cast converts within inheritance hierarchies const_cast adds or removes cv-qualifiers reinterpret_cast converts type to unrelated type C-style cast converts one type to another by a mix of static_cast, const_cast, and reinterpret_cast new creates objects with dynamic storage duration delete destructs objects previously created by the new expression and releases obtained memory area sizeof queries the size of a type sizeof... queries the size of a pack (since C++11) typeid queries the type information of a type noexcept checks if an expression can throw an exception (since C++11) alignof queries alignment requirements of a type (since C++11) |