Операторы инкремента/декремента
Операторы инкремента /декремента инкрементируют или декрементируют значение объекта.
| Имя оператора | Синтаксис | Перегружаемый | Примеры прототипов (для 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 встроенного префиксного оператора инкремента или декремента должен быть изменяемым (неконстантным) lvalue не логического (начиная с C++17) арифметического типа или указателем на полностью определённый объектный тип. Выражение ++x в точности эквивалентно x += 1 для небулевых операндов (до C++17), а выражение --x в точности эквивалентно x -= 1, то есть префиксные инкремент или декремент являетются выражением lvalue, которое идентифицирует изменённый операнд. Все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов, применяются и определяют неявное преобразование (если есть), применяемое к операнду, а также тип возвращаемого выражения.
Если операнд оператора префиксного инкремента имеет тип bool, он устанавливается в true (устарело). (до C++17)
В разрешении перегрузки для пользовательских операторов, для каждого арифметического типа A, который может быть volatile-квалифицирован, кроме bool, и для каждого необязательно volatile-квалифицированного указателя P на необязательно cv-квалифицированный тип объекта, следующие сигнатуры функций участвуют в разрешении перегрузки:
A& operator++(A&) |
||
bool& operator++(bool&) |
(устарело)(до C++17) | |
P& operator++(P&) |
||
A& operator--(A&) |
||
P& operator--(P&) |
||
Встроенные постфиксные операторы
Выражения постфиксного инкремента и декремента имеют форму
expr ++
|
|||||||||
expr --
|
|||||||||
Операнд expr встроенного постфиксного оператора инкремента или декремента должен быть изменяемым (неконстантным) lvalue небулевым (начиная с C++17) арифметическим типом или указателем на полностью определённый объектный тип. В результате получается prvalue копия исходного значения операнда. В качестве побочного эффекта выражение x++ изменяет значение своего операнда, как если бы оно вычисляло x += 1 для небулевых операндов (до C++17), а выражение x-- изменяет значение своего операнда, как если бы оно вычисляло x -= 1. Все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов применяются и определяют неявное преобразование (если есть), применяемое к операнду, а также тип возвращаемого выражения.
Если операнд оператора постинкремента имеет тип bool, он устанавливается в true (устарело). (до C++17)
В разрешении перегрузки для пользовательских операторов, для каждого арифметического типа A, который может быть volatile-квалифицированным, кроме 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++ ++; // ошибка
// int n6 = n1 + ++n1; // неопределённое поведение
std::cout << "n1 = " << n1 << '\n'
<< "n2 = " << n2 << '\n'
<< "n3 = " << n3 << '\n'
<< "n4 = " << n4 << '\n';
}
Вывод:
n1 = 5
n2 = 2
n3 = 4
n4 = 4
Примечание
Из-за побочных эффектов встроенные операторы инкремента и декремента необходимо использовать с осторожностью, чтобы избежать неопределённого поведения из-за нарушений правил последовательности.
Поскольку во время пост-инкремента и пост-декремента создаётся временная копия объекта, операторы пре-инкремента или пре-декремента обычно более эффективны в контекстах, где возвращаемое значение не используется.
Стандартные библиотеки
Операторы инкремента и декремента перегружены для многих стандартных типов библиотек. В частности, каждый LegacyIterator перегружает operator++, а каждый LegacyBidirectionalIterator перегружает operator--, даже если эти операторы не выполняются для конкретного итератора.
перегрузки для арифметических типов | |
| увеличивает или уменьшает атомарное значение на единицу (public функция-элемент std::atomic)
| |
| увеличивает или уменьшает количество тактов (public функция-элемент std::chrono::duration<Rep,Period>)
| |
перегрузки для типов итераторов | |
| продвигает итератор (public функция-элемент std::raw_storage_iterator)
| |
| увеличивает или уменьшает итератор (public функция-элемент std::reverse_iterator)
| |
| увеличивает или уменьшает итератор (public функция-элемент std::move_iterator)
| |
| нет операции (public функция-элемент std::front_insert_iterator)
| |
| нет операции (public функция-элемент std::back_insert_iterator)
| |
| нет операции (public функция-элемент std::insert_iterator)
| |
| продвигает итератор (public функция-элемент std::istream_iterator)
| |
| нет операции (public функция-элемент std::ostream_iterator)
| |
| продвигает итератор (public функция-элемент std::istreambuf_iterator)
| |
| нет операции (public функция-элемент std::ostreambuf_iterator)
| |
| продвигает итератор к следующему совпадению (public функция-элемент std::regex_iterator)
| |
| продвигает итератор к следующему подсовпадению (public функция-элемент std::regex_token_iterator)
| |
Смотрите также
| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание | инкремент декремент |
арифметические | логические | сравнения | доступ к элементу | другие |
|
|
|
|
|
|
|
вызов функции |
a(...)
| ||||||
| запятая | ||||||
a, b
| ||||||
| условный | ||||||
a ? b : c
| ||||||
| Специальные операторы | ||||||
|
static_cast приводит один тип к другому совместимому типу | ||||||
Документация C по Операторы инкремента/декремента
|