Difference between revisions of "cpp/language/operator incdec"
m (→Explanation) |
m (Mark 'for non-boolean operands' restrictions 'until C++17'.) |
||
Line 60: | Line 60: | ||
@2@ prefix decrement (pre-decrement) | @2@ prefix decrement (pre-decrement) | ||
− | The operand {{spar|expr}} of a built-in prefix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of {{rev inl|since=c++17|non-boolean}} arithmetic type or pointer to completely-defined {{rlp|type|object type}}. | + | The operand {{spar|expr}} of a built-in prefix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of {{rev inl|since=c++17|non-boolean}} arithmetic type or pointer to completely-defined {{rlp|type|object type}}. The expression {{c|++x}} is exactly equivalent to {{c|1=x += 1}}{{rev inl|until=c++17| for non-boolean operands}}, and the expression {{c|--x}} is exactly equivalent to {{c|1=x -= 1}}, that is, the prefix increment or decrement is an lvalue expression that identifies the modified operand. All arithmetic conversion rules and pointer arithmetic rules defined for {{rlp|operator_arithmetic|arithmetic operators}} apply and determine the implicit conversion (if any) applied to the operand as well as the return type of the expression. |
{{rev inl|until=c++17|If the operand of the pre-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}.}} | {{rev inl|until=c++17|If the operand of the pre-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}.}} | ||
Line 82: | Line 82: | ||
@2@ postfix decrement (post-decrement) | @2@ postfix decrement (post-decrement) | ||
− | The operand {{spar|expr}} of a built-in postfix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of {{rev inl|since=c++17|non-boolean}} arithmetic type or pointer to completely-defined {{rlp|type|object type}}. The result is {{rlp|value category|prvalue}} copy of the original value of the operand. As a side-effect | + | The operand {{spar|expr}} of a built-in postfix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of {{rev inl|since=c++17|non-boolean}} arithmetic type or pointer to completely-defined {{rlp|type|object type}}. The result is {{rlp|value category|prvalue}} copy of the original value of the operand. As a side-effect, the expression {{c|x++}} modifies the value of its operand as if by evaluating {{c|1=x += 1}}{{rev inl|until=c++17| for non-boolean operands}}, and the expression {{c|x--}} modifies the value of its operand as if by evaluating {{c|1=x -= 1}}. All arithmetic conversion rules and pointer arithmetic rules defined for {{rlp|operator_arithmetic|arithmetic operators}} apply and determine the implicit conversion (if any) applied to the operand as well as the return type of the expression. |
{{rev inl|until=c++17|If the operand of the post-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}.}} | {{rev inl|until=c++17|If the operand of the post-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}.}} |
Revision as of 01:05, 2 February 2021
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 |
Explanation
Pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.
Post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.
Using an lvalue of volatile-qualified non-class type as operand of built-in version of these operators is deprecated. |
(since C++20) |
Built-in prefix operators
The prefix increment and decrement expressions have the form
++ expr
|
|||||||||
-- expr
|
|||||||||
The operand expr of a built-in prefix increment or decrement operator must be a modifiable (non-const) lvalue of non-boolean(since C++17) arithmetic type or pointer to completely-defined object type. The expression ++x is exactly equivalent to x += 1 for non-boolean operands(until C++17), and the expression --x is exactly equivalent to x -= 1, that is, the prefix increment or decrement is an lvalue expression that identifies the modified operand. All arithmetic conversion rules and pointer arithmetic rules defined for arithmetic operators apply and determine the implicit conversion (if any) applied to the operand as well as the return type of the expression.
If the operand of the pre-increment operator is of type bool, it is set to true (deprecated).(until C++17)
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&) |
||
Built-in postfix operators
The postfix increment and decrement expressions have the form
expr ++
|
|||||||||
expr --
|
|||||||||
The operand expr of a built-in postfix increment or decrement operator must be a modifiable (non-const) lvalue of non-boolean(since C++17) arithmetic type or pointer to completely-defined object type. The result is prvalue copy of the original value of the operand. As a side-effect, the expression x++ modifies the value of its operand as if by evaluating x += 1 for non-boolean operands(until C++17), and the expression x-- modifies the value of its operand as if by evaluating x -= 1. All arithmetic conversion rules and pointer arithmetic rules defined for arithmetic operators apply and determine the implicit conversion (if any) applied to the operand as well as the return type of the expression.
If the operand of the post-increment operator is of type bool, it is set to true (deprecated).(until C++17)
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) |
||
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
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.
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> )
| |
increments or decrements the tick count (public member function of std::chrono::duration<Rep,Period> )
| |
overloads for iterator types | |
advances the iterator (public member function of std::raw_storage_iterator<OutputIt,T> )
| |
advances or decrements the iterator (public member function of std::reverse_iterator<Iter> )
| |
advances or decrements the iterator (public member function of std::move_iterator<Iter> )
| |
no-op (public member function of std::front_insert_iterator<Container> )
| |
no-op (public member function of std::back_insert_iterator<Container> )
| |
no-op (public member function of std::insert_iterator<Container> )
| |
advances the iterator (public member function of std::istream_iterator<T,CharT,Traits,Distance> )
| |
no-op (public member function of std::ostream_iterator<T,CharT,Traits> )
| |
advances the iterator (public member function of std::istreambuf_iterator<CharT,Traits> )
| |
no-op (public member function of std::ostreambuf_iterator<CharT,Traits> )
| |
advances the iterator to the next match (public member function of std::regex_iterator<BidirIt,CharT,Traits> )
| |
advances the iterator to the next submatch (public member function of std::regex_token_iterator<BidirIt,CharT,Traits> )
|
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 |
C documentation for Increment/decrement operators
|