Difference between revisions of "cpp/language/operator incdec"
m (if anything, an "inside class" call would be just "operator++(2)") |
|||
Line 39: | Line 39: | ||
| colspan="5" | | | colspan="5" | | ||
:'''Notes'''<br> | :'''Notes'''<br> | ||
− | * Prefix | + | * Prefix versions of the built-in operators return ''references'' and postfix versions return ''values'', and typical {{rlp|operators|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 {{c|void}}). |
− | * The {{c|int}} parameter is a dummy parameter used to differentiate between | + | * The {{c|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., {{c|a.operator++(2)}} or {{c|operator++(a, 2)}}). |
|} | |} | ||
===Explanation=== | ===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. |
====Built-in prefix operators==== | ====Built-in prefix operators==== | ||
Line 58: | Line 58: | ||
{{dcl end}} | {{dcl end}} | ||
− | The operand of a built-in prefix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of non-boolean arithmetic type or pointer to complete {{rlp|type|object type}}. | + | The operand of a built-in prefix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of non-boolean arithmetic type or pointer to complete {{rlp|type|object type}}. The expression {{c|++x}} is exactly equivalent to {{c|1=x += 1}}, and the expression {{c|--x}} is exactly equivalent to {{c|1=x -= 1}}, that is, the result is a reference to the modified value of the operand, returned as lvalue. All arithmetic conversion rules and pointer arithmetic rules defined for [[cpp/language/operator_arithmetic|arithmetic operators]] apply. |
− | If the operand of the | + | If the operand of the pre-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}. |
====Built-in postfix operators==== | ====Built-in postfix operators==== | ||
Line 72: | Line 72: | ||
{{dcl end}} | {{dcl end}} | ||
− | The operand of a built-in postfix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of non-boolean arithmetic type or pointer to complete {{rlp|type|object type}}. The result | + | The operand of a built-in postfix increment or decrement operator must be a modifiable (non-const) {{rlp|value category|lvalue}} of non-boolean arithmetic type or pointer to complete {{rlp|type|object type}}. The result is a copy of the original value of the operand, returned as {{rlp|value category|prvalue}}. As a side-effect, the expression {{c|x++}} modifies the value of its operand as if by evaluating {{c|1=x += 1}}, 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 [[cpp/language/operator_arithmetic|arithmetic operators]] apply. |
If the operand of the post-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}. | If the operand of the post-increment operator is of type {{c|bool}}, it is set to {{c|true}} {{mark deprecated}}. |
Revision as of 10:20, 24 August 2015
Increment/decrement operators increments or decrements 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.
Built-in prefix 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) | |
P& operator++(P&) |
||
A& operator--(A&) |
||
P& operator--(P&) |
||
The operand of a built-in prefix increment or decrement operator must be a modifiable (non-const) lvalue of non-boolean arithmetic type or pointer to complete object type. The expression ++x is exactly equivalent to x += 1, and the expression --x is exactly equivalent to x -= 1, that is, the result is a reference to the modified value of the operand, returned as lvalue. All arithmetic conversion rules and pointer arithmetic rules defined for arithmetic operators apply.
If the operand of the pre-increment operator is of type bool, it is set to true (deprecated).
Built-in postfix 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) | |
P operator++(P&, int) |
||
A operator--(A&, int) |
||
P operator--(P&, int) |
||
The operand of a built-in postfix increment or decrement operator must be a modifiable (non-const) lvalue of non-boolean arithmetic type or pointer to complete object type. The result is a copy of the original value of the operand, returned as prvalue. As a side-effect, the expression x++ modifies the value of its operand as if by evaluating x += 1, and the expression --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 arithmetic operators apply.
If the operand of the post-increment operator is of type bool, it is set to true (deprecated).
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 Template:concept overloads operator++ and every Template:concept 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 |