Increment/decrement operators
Операторы инкремента/декремента увеличивают или уменьшают значение объекта.
| Название оператора | Синтаксис | Перегружаемый | Примеры прототипов (для 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 ) ; |
|
||||
Содержание |
Префиксные операторы
Выражения префиксного инкремента и декремента имеют вид
++
выражение
|
|||||||||
--
выражение
|
|||||||||
Встроенные префиксные операторы
|
(до C++17) |
|
(начиная с C++17) |
|
(начиная с C++20) |
- Если тип выражения является (возможно cv-квалифицированным) bool , программа является некорректной.
|
(since C++20) |
Перегрузки
В
разрешении перегрузки для пользовательских операторов
, для каждого опционально volatile-квалифицированного арифметического типа
A
кроме
bool
, и для каждого опционально volatile-квалифицированного указателя
P
на опционально cv-квалифицированный объектный тип, следующие сигнатуры функций участвуют в разрешении перегрузки:
|
A
&
operator
++
(
A
&
)
|
||
|
bool
&
operator
++
(
bool
&
)
|
(устарело) (до C++17) | |
|
P
&
operator
++
(
P
&
)
|
||
|
A
&
operator
--
(
A
&
)
|
||
|
P
&
operator
--
(
P
&
)
|
||
Постфиксные операторы
Выражения постфиксного инкремента и декремента имеют вид
выражение
++
|
|||||||||
выражение
--
|
|||||||||
Встроенные постфиксные операторы
Результатом постфиксного инкремента или декремента является значение, полученное применением преобразования lvalue-в-rvalue к expression (до модификации). Тип результата — это версия типа expression без cv-квалификаторов.
Если expression не является модифицируемым lvalue арифметического типа отличного от (возможно cv-квалифицированного) bool (since C++17) , или указателем на полный объектный тип, программа является некорректной.
|
Если тип expression квалифицирован как volatile, инкремент или декремент устарел. |
(since C++20) |
++
.
--
.
Вычисление значения постфиксного инкремента или декремента упорядочено перед модификацией expression . По отношению к неопределённо упорядоченному вызову функции операция постфиксного инкремента или декремента является единым вычислением.
Перегрузки
В
разрешении перегрузки для пользовательских операторов
, для каждого опционально 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++ ++; // ошибка // 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 -- , даже если эти операторы являются no-ops для конкретного итератора.
перегрузки для арифметических типов |
|
|
увеличивает или уменьшает атомарное значение на единицу
(публичная функция-член
std::atomic<T>
)
|
|
|
увеличивает или уменьшает количество тактов
(публичная функция-член
std::chrono::duration<Rep,Period>
)
|
|
перегрузки для типов итераторов |
|
|
перемещает итератор вперед
(публичная функция-член
std::raw_storage_iterator<OutputIt,T>
)
|
|
перемещает вперед или назад
reverse_iterator
(публичная функция-член
std::reverse_iterator<Iter>
)
|
|
перемещает вперед или назад
move_iterator
(публичная функция-член
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>
)
|
|
Отчеты о дефектах
Следующие отчеты об изменениях в поведении, являющиеся дефектами, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| CWG 2855 | C++98 |
usual arithmetic conversions are applied for built-in pre-increment and
pre-decrement, but were not applied for their postfix counterparts [1] |
also applied |
| CWG 2901 | C++98 |
lvalue-to-rvalue conversions were not applied
for built-in post-increment and post-decrement |
applied |
- ↑ Префиксная форма ++ x эквивалентна x + = 1 , и последняя подлежит обычным арифметическим преобразованиям (т.е. приводит к общему типу между decltype ( x ) и int ). Однако эффект постфиксной формы x ++ просто "добавляет единицу к x ", бинарный оператор отсутствует, поэтому обычные арифметические преобразования не выполняются.
Смотрите также
| Основные операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание |
инкремент
декремент |
арифметические | логические | сравнения |
доступа к
членам |
прочие |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
вызов функции
a ( ... ) |
|
запятая
a, b |
||||||
|
условный оператор
a ? b : c |
||||||
| Специальные операторы | ||||||
|
static_cast
преобразует один тип в другой связанный тип
|
||||||
|
Документация по C
для
Операторы инкремента/декремента
|