Namespaces
Variants
Views
Actions

Increment/decrement operators

From cppreference.com
< cpp‎ | language
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Increment/decrement operators increment or decrement the value of the object.

Operator name Syntax Over​load​able 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
1) prefix increment (pre-increment)
2) prefix decrement (pre-decrement)

[edit] Built-in prefix operators

1) 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)
2) 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 --
1) postfix increment (post-increment)
2) postfix decrement (post-decrement)

[edit] Built-in postfix operators

The result of postfix increment or decrement is a prvalue copy of 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)
1) The value of expression is modified as if it were the operand of the prefix ++ operator.
2) 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 <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
increments or decrements the atomic value by one
(public member function of std::atomic<T>) [edit]
increments or decrements the tick count
(public member function of std::chrono::duration<Rep,Period>) [edit]
overloads for iterator types
advances the iterator
(public member function of std::raw_storage_iterator<OutputIt,T>) [edit]
advances or decrements the iterator
(public member function of std::reverse_iterator<Iter>) [edit]
advances or decrements the iterator
(public member function of std::move_iterator<Iter>) [edit]
no-op
(public member function of std::front_insert_iterator<Container>) [edit]
no-op
(public member function of std::back_insert_iterator<Container>) [edit]
no-op
(public member function of std::insert_iterator<Container>) [edit]
advances the iterator
(public member function of std::istream_iterator<T,CharT,Traits,Distance>) [edit]
no-op
(public member function of std::ostream_iterator<T,CharT,Traits>) [edit]
advances the iterator
(public member function of std::istreambuf_iterator<CharT,Traits>) [edit]
no-op
(public member function of std::ostreambuf_iterator<CharT,Traits>) [edit]
advances the iterator to the next match
(public member function of std::regex_iterator<BidirIt,CharT,Traits>) [edit]
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 pre-increment and
pre-decrement, but were not applied to their postfix counterparts[1]
also applied
  1. 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

Operator precedence

Operator overloading

Common operators
assignment increment
decrement
arithmetic logical comparison member
access
other

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

function call
a(...)
comma
a, b
conditional
a ? 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 parameter 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)

C documentation for Increment/decrement operators