Namespaces
Variants

Expressions

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

Una expresión es una secuencia de operadores y sus operandos , que especifica un cálculo.

La evaluación de expresiones puede producir un resultado (por ejemplo, la evaluación de 2 + 2 produce el resultado 4 ) y puede generar efectos secundarios (por ejemplo, la evaluación de std:: printf ( "%d" , 4 ) imprime el carácter '4' en la salida estándar).

Cada expresión en C++ se caracteriza por dos propiedades independientes: un tipo y una categoría de valor.

Contenidos

General

  • categorías de valor (lvalue, rvalue , glvalue, prvalue, xvalue (desde C++11) ) clasifican expresiones por sus valores
  • orden de evaluación de argumentos y subexpresiones especifica el orden en que se obtienen los resultados intermedios

Operadores

Operadores comunes
asignación incremento
decremento
aritmética lógica 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 verifica 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)

Conversiones

Asignación de memoria

Otros

Expresiones primarias

Los operandos de cualquier operador pueden ser otras expresiones o expresiones primarias (por ejemplo, en 1 + 2 * 3 , los operandos del operator+ son la subexpresión 2 * 3 y la expresión primaria 1 ).

Las expresiones primarias son cualquiera de las siguientes:

(desde C++26)
(desde C++11)
(desde C++17)
(desde C++20)

Cualquier expresión entre paréntesis también se clasifica como una expresión primaria: esto garantiza que los paréntesis tengan mayor precedencia que cualquier operador. Los paréntesis preservan el valor, el tipo y la categoría de valor.

Literales

Los literales son los tokens de un programa C++ que representan valores constantes incrustados en el código fuente.

  • char o wchar_t
  • char16_t o char32_t
(desde C++11)
  • char8_t
(desde C++20)
  • const char [ ] o const wchar_t [ ]
  • const char16_t [ ] o const char32_t [ ]
(desde C++11)
  • const char8_t [ ]
(desde C++20)
(desde C++11)

Expresiones completas

Una expresión constituyente se define de la siguiente manera:

  • La expresión constituyente de una expresión es esa expresión.
  • Las expresiones constituyentes de una lista de inicialización entre llaves o de una lista de expresiones (posiblemente entre paréntesis) son las expresiones constituyentes de los elementos de la lista respectiva.
  • Las expresiones constituyentes de un inicializador que comienza con = son las expresiones constituyentes de la cláusula-de-inicializador .
int num1 = 0;
num1 += 1; // Caso 1: la expresión constituyente de "num += 1" es "num += 1"
int arr2[2] = {2, 22} // Caso 2: las expresiones constituyentes
                      //         de "{2, 22}" son "2" y "22"
                      // Caso 3: las expresiones constituyentes de "= {2, 22}"
                      //         son las expresiones constituyentes de "{2, 22}"
                      //         (es decir, también "2" y "22")

Las subexpresiones inmediatas de una expresión E son

  • las expresiones constituyentes de E operandos,
(desde C++14)
  • si E es una expresión lambda , la inicialización de las entidades capturadas por copia y las expresiones constituyentes del inicializador de las capturas,
(desde C++11)
  • cualquier llamada a función que E invoque implícitamente, o
  • si E es una llamada a función o invoca implícitamente una función, las expresiones constituyentes de cada argumento por defecto utilizado en la llamada.

Una subexpresión de una expresión E es una subexpresión inmediata de E o una subexpresión de una subexpresión inmediata de E . Nótese que las expresiones que aparecen en el "cuerpo de función" de las expresiones lambda no son subexpresiones de la expresión lambda. (desde C++11)

Las siguientes expresiones son expresiones completas  :

(desde C++20)
(desde C++26)
  • expresiones que no son una subexpresión de ninguna otra expresión y que no forman parte de ninguna expresión completa

Si una construcción del lenguaje está definida para producir una llamada implícita de una función, el uso de dicha construcción se considera una expresión para los propósitos de esta definición. Las conversiones aplicadas al resultado de una expresión para satisfacer los requisitos de la construcción del lenguaje en la que aparece la expresión también se consideran parte de la expresión completa.

Para un inicializador, realizar la inicialización de la entidad (incluyendo evaluar inicializadores predeterminados de miembros de un agregado) (desde C++14) también se considera parte de la expresión completa.

Expresiones potencialmente evaluadas

Una expresión es potencialmente evaluada a menos que

(hasta C++11)

Los siguientes operandos son operandos no evaluados , no se evalúan:

(desde C++20)

Una expresión es potencialmente evaluada a menos que

  • sea un operando no evaluado, o
  • sea una subexpresión de un operando no evaluado.
(desde C++11)

Las expresiones potencialmente evaluadas son ODR-use .

Expresiones de valor descartado

Una expresión de valor descartado es una expresión que se utiliza únicamente por sus efectos secundarios. El valor calculado a partir de dicha expresión se descarta. Tales expresiones incluyen la expresión completa de cualquier sentencia de expresión , el operando izquierdo del operador coma incorporado, o el operando de una expresión de conversión que convierte al tipo void .

Las conversiones de array-a-puntero y función-a-puntero nunca se aplican al valor calculado por una expresión de valor descartado. La conversión de lvalue-a-rvalue se aplica si y solo si la expresión es un glvalue calificado volatile y tiene una de las siguientes formas (significado built-in requerido, posiblemente entre paréntesis):

  • expresión de identificación,
  • expresión de subíndice de arreglo,
  • expresión de acceso a miembro de clase,
  • indirección,
  • operación de puntero a miembro,
  • expresión condicional donde tanto el segundo como el tercer operando son una de estas expresiones,
  • expresión coma donde el operando derecho es una de estas expresiones.

Además, si el lvalue es de tipo clase calificado como volátil, se requiere un constructor de copia volátil para inicializar el temporal resultante del rvalue.

Si la expresión es un prvalue no void (después de cualquier conversión de lvalue-a-rvalue que pueda haber ocurrido), ocurre materialización temporal .

Los compiladores pueden emitir advertencias cuando una expresión diferente a la conversión a void descarta un valor declarado con [[ nodiscard ]] .

(desde C++17)

Equivalencia-de-expresión

Un conjunto de expresiones e1 , e2 , ..., eN son equivalentes en expresión si se cumplen todas las siguientes condiciones:

  1. Tienen los mismos efectos.
  2. O todas son subexpresiones constantes o ninguna lo es.
  3. O todas son noexcept o ninguna lo es.

e1 es equivalente en expresión a e2 si y solo si e1 y e2 son equivalentes en expresión (lo que significa que e2 también es equivalente en expresión a e1 ).

(desde C++20)

Informes de defectos

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

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 1054 C++98 asignar un valor a una variable volatile podría
resultar en una lectura innecesaria debido a la conversión
de lvalue-a-rvalue aplicada al resultado de la asignación
introducir expresiones de valor descartado
y excluir este caso de la lista
de casos que requieren la conversión
CWG 1343 C++98 la secuenciación de llamadas a destructores en
inicialización de agregados estaba subespecificada
las expresiones-completas en inicialización de agregados
están bien especificadas
CWG 1383 C++98 la lista de expresiones donde la conversión lvalue-a-rvalue
se aplica a expresiones de valor descartado
también cubría operadores sobrecargados
cubrir solo operadores
con significado incorporado
CWG 1576 C++11 las conversiones lvalue-a-rvalue no se aplicaban
a expresiones de valor descartado volatile xvalue
aplicar la conversión
en este caso
CWG 2249 C++98 los identificadores a declarar en declaradores
no eran expresiones-id
lo son
CWG 2431 C++11 las invocaciones de los destructores de temporales que
están ligados a referencias no eran expresiones-completas
lo son

Véase también

Documentación de C para Expresiones