Операторы инкремента/декремента
Операторы инкремента/декремента увеличивают или уменьшают значение объекта.
| Имя оператора | Синтаксис | Перегружаемый | Примеры прототипов (для class T) |
|
|---|---|---|---|---|
| Внутри определения класса | Вне определения класса | |||
| Префиксный инкремент |
++a | Да |
T& T::operator++(); |
T& operator++(T& a); |
| Префиксный декремент |
--a | Да |
T& T::operator--(); |
T& operator--(T& a); |
| Постфиксный инкремент |
a++ | Да |
T T::operator++(int); |
T operator++(T& a, int); |
| Постфиксный декремент |
a-- | Да |
T T::operator--(int); |
T operator--(T& a, int); |
Примечания
|
||||
Объяснение
Операторы префиксного инкремента и префиксного декремента увеличивают или уменьшают значение объекта и возвращают ссылку на результат.
Операторы постфиксного инкремента и постфиксного декремента создают копию объекта, увеличивают или уменьшают значение объекта и возвращают копию до инкремента или декремента.
| Использование lvalue с квалификатором volatile неклассового типа в качестве операнда встроенной версии этих операторов устарело. | (с C++20) |
Встроенные префиксные операторы
Выражения префиксного инкремента и декремента имеют вид
++ expr | ||
-- expr |
Операнд expr встроенного префиксного оператора инкремента или декремента должен быть изменяемым (не const) lvalue арифметического типа (не bool) или указателя на полностью определённый тип объекта. Выражение ++x точно эквивалентно x += 1, а выражение --x точно эквивалентно x -= 1, то есть префиксный инкремент или декремент — это выражение lvalue, которое идентифицирует изменённый операнд. Применяются все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов, которые определяют применяемое (при необходимости) неявное преобразование операнда и тип возвращаемого значения выражения.
Если операнд оператора префиксного инкремента имеет тип bool, он устанавливается в true (устарело).(до C++17)
При разрешении перегрузки по отношению к пользовательским операторам для каждого необязательно квалифицированного volatile арифметического типа A отличного от bool, и для каждого необязательно квалифицированного volatile указателя P на необязательно cv-квалифицированный тип объекта участвуют следующие сигнатуры функций:
A& operator++(A&) | ||
bool& operator++(bool&) | (устарело)(до C++17) | |
P& operator++(P&) | ||
A& operator--(A&) | ||
P& operator--(P&) |
Встроенные постфиксные операторы
Выражения постфиксного инкремента и декремента имеют вид
expr ++ | ||
expr -- |
Операнд expr встроенного постфиксного оператора инкремента или декремента должен быть изменяемым (не const) lvalue арифметического типа (не bool) или указателя на полностью определённый тип объекта. Результатом является prvalue копия исходного значения операнда. В качестве побочного эффекта выражение x++ изменяет значение своего операнда так, как если бы оно оценивалось как x += 1, а выражение x-- изменяет значение своего операнда так, как если бы оно оценивалось как x -= 1. Все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов, применяются и определяют применяемое (при необходимости) неявное преобразование операнда и тип возвращаемого значения выражения.
Если операнд оператора постфиксного инкремента имеет тип bool, он устанавливается в true (устарело).(до C++17)
При разрешении перегрузки по отношению к пользовательским операторам для каждого необязательно квалифицированного volatile арифметического типа A отличного от bool, и для каждого необязательно квалифицированного volatile указателя P на необязательно cv-квалифицированный тип объекта участвуют следующие сигнатуры функций:
A operator++(A&, int) | ||
bool operator++(bool&, int) | (устарело)(до C++17) | |
P operator++(P&, int) | ||
A operator--(A&, int) | ||
P operator--(P&, int) |
Пример
#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';
}Вывод:
n1 = 5 n2 = 2 n3 = 4 n4 = 4
Примечания
Из-за вовлечённых побочных эффектов встроенные операторы инкремента и декремента следует использовать с осторожностью, чтобы избежать неопределённого поведения из-за нарушения правил последовательности.
Из-за создания временной копии объекта во время постфиксного инкремента и декремента операторы префиксного инкремента или префиксного декремента обычно более эффективны в контекстах, где возвращаемое значение не используется.
Стандартная библиотека
Операторы инкремента и декремента перегружены для многих типов стандартной библиотеки. В частности, каждый LegacyIterator перегружает оператор++, а каждый LegacyBidirectionalIterator перегружает оператор--, даже если эти операторы являются пустыми операциями для конкретного итератора.
END_OF_DOCUMENT_MARKER Перегрузки для арифметических типов |
|
| инкрементирует или декрементирует атомное значение на единицу (публичный член-функция std::atomic<T>) |
|
| инкрементирует или декрементирует значение отсчёта (публичный член-функция std::chrono::duration<Rep,Period>) |
|
Перегрузки для типов итераторов |
|
| перемещает итератор вперёд (публичный член-функция std::raw_storage_iterator<OutputIt,T>) |
|
| перемещает итератор вперёд или назад (публичный член-функция std::reverse_iterator<Iter>) |
|
|
(C++11) | перемещает итератор вперёд или назад (публичный член-функция std::move_iterator<Iter>) |
| пустая операция (публичный член-функция std::front_insert_iterator<Container>) |
|
| пустая операция (публичный член-функция std::back_insert_iterator<Container>) |
|
| пустая операция (публичный член-функция std::insert_iterator<Container>) |
|
| перемещает итератор вперёд (публичный член-функция std::istream_iterator<T,CharT,Traits,Distance>) |
|
| пустая операция (публичный член-функция std::ostream_iterator<T,CharT,Traits>) |
|
| перемещает итератор вперёд (публичный член-функция std::istreambuf_iterator<CharT,Traits>) |
|
| пустая операция (публичный член-функция std::ostreambuf_iterator<CharT,Traits>) |
|
| перемещает итератор к следующему совпадению (публичный член-функция std::regex_iterator<BidirIt,CharT,Traits>) |
|
| перемещает итератор к следующему подсовпадению (публичный член-функция std::regex_token_iterator<BidirIt,CharT,Traits>) |
|
См. также
| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание |
инкремент декремент | арифметические | логические | сравнения | доступ к членам | прочие |
|
|
|
|
|
|
| вызов функции |
a(...) |
||||||
| запятая | ||||||
a, b |
||||||
| условный | ||||||
a ? b : c |
||||||
| Специальные операторы | ||||||
|
|
||||||
| C документация для Операторы инкремента/декремента |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/operator_incdec