Spec-Zone.ru › C++

Операторы инкремента/декремента

Операторы инкремента/декремента увеличивают или уменьшают значение объекта.

Имя оператора Синтаксис Перегружаемый Примеры прототипов (для 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);
Примечания
  • Префиксные версии встроенных операторов возвращают ссылки, а постфиксные — значения, и типичные перегрузки пользовательских операторов следуют этому шаблону, чтобы пользовательские операторы можно было использовать так же, как и встроенные. Однако в перегрузке пользовательского оператора можно использовать любой тип в качестве типа возвращаемого значения (включая void).
  • Параметр int — это фиктивный параметр, используемый для различения префиксных и постфиксных версий операторов. При вызове пользовательского постфиксного оператора значение, переданное в этот параметр, всегда равно нулю, хотя оно может быть изменено при вызове оператора с помощью нотации вызова функции (например, a.operator++(2) или operator++(a, 2)).

Объяснение

Операторы префиксного инкремента и префиксного декремента увеличивают или уменьшают значение объекта и возвращают ссылку на результат.

Операторы постфиксного инкремента и постфиксного декремента создают копию объекта, увеличивают или уменьшают значение объекта и возвращают копию до инкремента или декремента.

Использование lvalue с квалификатором volatile неклассового типа в качестве операнда встроенной версии этих операторов устарело.

(с C++20)

Встроенные префиксные операторы

Выражения префиксного инкремента и декремента имеют вид

++ expr
-- expr
1) префиксный инкремент (префиксный инкремент)
2) префиксный декремент (префиксный декремент)

Операнд 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 --
1) постфиксный инкремент (постфиксный инкремент)
2) постфиксный декремент (постфиксный декремент)

Операнд 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
Перегрузки для арифметических типов
operator++operator++(int)operator--operator--(int)
инкрементирует или декрементирует атомное значение на единицу
(публичный член-функция std::atomic<T>)
operator++operator++(int)operator--operator--(int)
инкрементирует или декрементирует значение отсчёта
(публичный член-функция std::chrono::duration<Rep,Period>)
Перегрузки для типов итераторов
operator++operator++(int)
перемещает итератор вперёд
(публичный член-функция std::raw_storage_iterator<OutputIt,T>)
operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator-
перемещает итератор вперёд или назад
(публичный член-функция std::reverse_iterator<Iter>)
operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator-
(C++11)
перемещает итератор вперёд или назад
(публичный член-функция std::move_iterator<Iter>)
operator++operator++(int)
пустая операция
(публичный член-функция std::front_insert_iterator<Container>)
operator++operator++(int)
пустая операция
(публичный член-функция std::back_insert_iterator<Container>)
operator++operator++(int)
пустая операция
(публичный член-функция std::insert_iterator<Container>)
operator++operator++(int)
перемещает итератор вперёд
(публичный член-функция std::istream_iterator<T,CharT,Traits,Distance>)
operator++operator++(int)
пустая операция
(публичный член-функция std::ostream_iterator<T,CharT,Traits>)
operator++operator++(int)
перемещает итератор вперёд
(публичный член-функция std::istreambuf_iterator<CharT,Traits>)
operator++operator++(int)
пустая операция
(публичный член-функция std::ostreambuf_iterator<CharT,Traits>)
operator++operator++(int)
перемещает итератор к следующему совпадению
(публичный член-функция std::regex_iterator<BidirIt,CharT,Traits>)
operator++operator++(int)
перемещает итератор к следующему подсовпадению
(публичный член-функция std::regex_token_iterator<BidirIt,CharT,Traits>)

См. также

Порядок выполнения операций

Перегрузка операторов

Общие операторы
присваивание инкремент
декремент
арифметические логические сравнения доступ к членам прочие

a = b a += b a -= b a *= b a /= b a %= b a &= b a |= b a ^= b a <<= b a >>= b

++a --a a++ a--

+a -a a + b a - b a * b a / b a % b ~a a & b a | b a ^ b a << b a >> b

!a a && b a || b

a == b a != b a < b a > b a <= b a >= b a <=> b

a[...] *a &a a->b a.b a->*b a.*b

вызов функции
a(...)
запятая
a, b
условный
a ? b : c
Специальные операторы

static_cast преобразует один тип в другой родственный тип
dynamic_cast преобразует в иерархии наследования
const_cast добавляет или удаляет квалификаторы cv
reinterpret_cast преобразует тип в неродственный
Каст в стиле C преобразует один тип в другой, комбинируя static_cast, const_cast, и reinterpret_cast
new создаёт объекты с динамической длиной хранения
delete уничтожает объекты, созданные оператором new, и освобождает занимаемую область памяти
sizeof запрашивает размер типа
sizeof... запрашивает размер параметра пакета параметров (с C++11)
typeid запрашивает информацию о типе типа
noexcept проверяет, может ли выражение бросить исключение (с C++11)
alignof запрашивает требования выравнивания типа (с C++11)

C документация для Операторы инкремента/декремента

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/operator_incdec

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API