Namespaces
Variants

Increment/decrement operators

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Los operadores de incremento/decremento incrementan o decrementan el valor del objeto.

Nombre del operador Sintaxis Sobrecargable Ejemplos de prototipo (para class T )
Dentro de la definición de clase Fuera de la definición de clase
pre-incremento ++a T & T :: operator ++ ( ) ; T & operator ++ ( T & a ) ;
pre-decremento --a T & T :: operator -- ( ) ; T & operator -- ( T & a ) ;
post-incremento a++ T T :: operator ++ ( int ) ; T operator ++ ( T & a, int ) ;
post-decremento a-- T T :: operator -- ( int ) ; T operator -- ( T & a, int ) ;
Notas
  • Las versiones prefijas de los operadores incorporados devuelven referencias y las versiones postfijas devuelven valores , y las sobrecargas definidas por el usuario típicas siguen este patrón para que los operadores definidos por el usuario puedan usarse de la misma manera que los incorporados. Sin embargo, en una sobrecarga de operador definida por el usuario, se puede usar cualquier tipo como tipo de retorno (incluyendo void ).
  • El parámetro int es un parámetro ficticio utilizado para diferenciar entre las versiones prefijas y postfijas de los operadores. Cuando se llama al operador postfijo definido por el usuario, el valor pasado en ese parámetro siempre es cero, aunque puede cambiarse llamando al operador usando notación de llamada a función (por ejemplo, a. operator ++ ( 2 ) o operator ++ ( a, 2 ) ).

Contenidos

Operadores de prefijo

Las expresiones de incremento y decremento prefijas tienen la forma

++ expresión
-- expresión
1) incremento de prefijo (pre-incremento)
2) decremento de prefijo (pre-decremento)

Operadores de prefijo incorporados

1) La expresión ++ x es equivalente a x + = 1 , con las siguientes excepciones:
  • Si el tipo de expression es (posiblemente calificado con volatile) bool , expression se establece en true . Tal incremento está obsoleto.
(hasta C++17)
  • Si el tipo de expression es (posiblemente calificado con cv) bool , el programa está mal formado.
(desde C++17)
  • Si el tipo de expression está calificado con volatile, el incremento está obsoleto.
(desde C++20)
2) La expresión -- x es equivalente a x - = 1 , con las siguientes excepciones:
  • Si el tipo de expresión es (posiblemente calificado cv) bool , el programa está mal formado.
  • Si el tipo de expresión está calificado volatile, el decremento está obsoleto.
(since C++20)

Sobrecargas

En la resolución de sobrecarga contra operadores definidos por el usuario , para cada tipo aritmético calificado opcionalmente como volátil A excepto bool , y para cada puntero opcionalmente calificado como volátil P a tipo de objeto opcionalmente calificado como cv, las siguientes firmas de función participan en la resolución de sobrecarga:

A & operator ++ ( A & )
bool & operator ++ ( bool & )
(obsoleto) (hasta C++17)
P & operator ++ ( P & )
A & operator -- ( A & )
P & operator -- ( P & )

Operadores postfijos

Las expresiones de incremento y decremento postfijas tienen la forma

expresión ++
expresión --
1) incremento postfijo (post-incremento)
2) decremento postfijo (post-decremento)

Operadores postfijos incorporados

El resultado del incremento o decremento postfijo es el valor obtenido aplicando la conversión de lvalue a rvalue a expression (antes de la modificación). El tipo del resultado es la versión sin calificadores cv del tipo de expression .

Si expresión no es un lvalue modificable de un tipo aritmético distinto de (posiblemente calificado como cv) bool (desde C++17) , o un puntero a un tipo de objeto completo, el programa está mal formado.

Si el tipo de expression está calificado como volatile, el incremento o decremento está obsoleto.

(since C++20)
1) El valor de la expresión se modifica como si fuera el operando del operador de prefijo ++ .
2) El valor de la expresión se modifica como si fuera el operando del operador de prefijo -- .

El cálculo del valor de un incremento o decremento postfijo está secuenciado antes de la modificación del expression . Con respecto a una llamada de función indeterminadamente secuenciada, la operación de un incremento o decremento postfijo es una única evaluación.

Sobrecargas

En la resolución de sobrecarga contra operadores definidos por el usuario , para cada tipo aritmético calificado opcionalmente como volátil A excepto bool , y para cada puntero opcionalmente calificado como volátil P a tipo de objeto opcionalmente calificado como cv, las siguientes firmas de función participan en la resolución de sobrecarga:

A operator ++ ( A & , int )
bool operator ++ ( bool & , int )
(obsoleto) (hasta C++17)
P operator ++ ( P & , int )
A operator -- ( A & , int )
P operator -- ( P & , int )

Ejemplo

#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';
}

Salida:

n1 = 5
n2 = 2
n3 = 4
n4 = 4

Notas

Debido a los efectos secundarios involucrados, los operadores integrados de incremento y decremento deben usarse con cuidado para evitar comportamiento indefinido debido a violaciones de las reglas de secuenciación .

Debido a que se construye una copia temporal del objeto durante el post-incremento y post-decremento, los operadores de pre-incremento o pre-decremento suelen ser más eficientes en contextos donde el valor devuelto no se utiliza.

Biblioteca estándar

Los operadores de incremento y decremento están sobrecargados para muchos tipos de la biblioteca estándar. En particular, cada LegacyIterator sobrecarga operator ++ y cada LegacyBidirectionalIterator sobrecarga operator -- , incluso si esos operadores no realizan ninguna operación para el iterador particular.

sobrecargas para tipos aritméticos
incrementa o decrementa el valor atómico en uno
(función miembro pública de std::atomic<T> )
incrementa o decrementa el conteo de ticks
(función miembro pública de std::chrono::duration<Rep,Period> )
sobrecargas para tipos iterador
avanza el iterador
(función miembro pública de std::raw_storage_iterator<OutputIt,T> )
avanza o retrocede el reverse_iterator
(función miembro pública de std::reverse_iterator<Iter> )
avanza o retrocede el move_iterator
(función miembro pública de std::move_iterator<Iter> )
operación nula
(función miembro pública de std::front_insert_iterator<Container> )
operación nula
(función miembro pública de std::back_insert_iterator<Container> )
operación nula
(función miembro pública de std::insert_iterator<Container> )
avanza el iterador
(función miembro pública de std::istream_iterator<T,CharT,Traits,Distance> )
operación nula
(función miembro pública de std::ostream_iterator<T,CharT,Traits> )
avanza el iterador
(función miembro pública de std::istreambuf_iterator<CharT,Traits> )
operación nula
(función miembro pública de std::ostreambuf_iterator<CharT,Traits> )
avanza el iterador a la siguiente coincidencia
(función miembro pública de std::regex_iterator<BidirIt,CharT,Traits> )
avanza el iterador a la siguiente subcoincidencia
(función miembro pública de std::regex_token_iterator<BidirIt,CharT,Traits> )

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Se aplica a Comportamiento publicado Comportamiento correcto
CWG 2855 C++98 las conversiones aritméticas usuales se aplicaban para el pre-incremento y
pre-decremento incorporados, pero no se aplicaban para sus contrapartes postfijas [1]
también aplicadas
CWG 2901 C++98 las conversiones de lvalue-a-rvalue no se aplicaban
para el post-incremento y post-decremento incorporados
aplicadas
  1. El prefijo ++ x es equivalente a x + = 1 , y este último es aplicable para conversiones aritméticas usuales (es decir, produce un tipo común entre decltype ( x ) e int ). Sin embargo, el efecto del postfijo x ++ es simplemente "sumar uno a x ", no hay ningún operador binario presente, por lo que no tendrán lugar conversiones aritméticas usuales.

Véase también

Precedencia de operadores

Sobrecarga de operadores

Operadores comunes
asignación incremento
decremento
aritméticos lógicos comparación acceso a
miembros
otros

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

llamada a función

a ( ... )
coma

a, b
condicional

a ? b : c
Operadores especiales

static_cast convierte un tipo a otro tipo relacionado
dynamic_cast convierte dentro de jerarquías de herencia
const_cast añade o elimina cv -calificadores
reinterpret_cast convierte un tipo a un tipo no relacionado
Conversión estilo C convierte un tipo a otro mediante una mezcla de static_cast , const_cast , y reinterpret_cast
new crea objetos con duración de almacenamiento dinámico
delete destruye objetos previamente creados por la expresión new y libera el área de memoria obtenida
sizeof consulta el tamaño de un tipo
sizeof... consulta el tamaño de un pack (desde C++11)
typeid consulta la información de tipo de un tipo
noexcept comprueba si una expresión puede lanzar una excepción (desde C++11)
alignof consulta los requisitos de alineación de un tipo (desde C++11)

Documentación de C para Operadores de incremento/decremento