Expresiones
Un expresión es una secuencia de operadores y sus operandos, que especifican un cálculo.
La evaluación de expresiones puede producir un resultado (p. ej., la evaluación de 2+2 produce el resultado 4) y puede generar otros efectos (p. ej., la evaluación de std::printf("%d",4) imprime en la salida estándar el carácter '4').
Cada expresión de C++ se caracteriza por dos propiedades independientes: un tipo y una categoría de valor.
Contenido |
[editar] General
- Las categorías de valor (l-valor, r-valor, gl-valor, pr-valor, x-valor) clasifican las expresiones según sus valores.
- El orden de evaluación de los argumentos y subexpresiones especifican el orden que se obtienen los resultados intermedios.
[editar] Operadores
Operadores comunes | ||||||
---|---|---|---|---|---|---|
Asignación | Incremento/decremento | Aritméticos | Lógicos | Comparación | Acceso a miembro | Otros |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
Operadores especiales | ||||||
static_cast Convierte de un tipo a otro tipo relacionado |
- La precedencia de operadores especifica el orden en que los operadores está ligados a sus argumentos.
- Las representaciones alternativas son códigos alternativos para algunos operadores.
- La sobrecarga de operadores hace posible la especificación de un comportamiento para los operadores en una clase definida por el usuario.
[editar] Conversiones
- Conversiones estándar implícitas de un tipo a otro
- Conversión
const_cast
. - Conversión
static_cast
. - Conversión
dynamic_cast
. - Conversión
reinterpret_cast
. - Conversión explícita
reinterpret_cast
usando la notación tipo C y la notación funcional. - Conversiones definidas por el usuario hace posible especificar la conversión de clases definidas por el usuario.
[editar] Asignación de memoria
- La expresión new asigna memoria dinámicamente.
- La expresión delete desasigna memoria dinámicamente.
[editar] Otros
- Las expresiones constantes se pueden evaluar en tiempo de compilación y utilizar en el contexto de tiempo de compilación (argumentos de plantilla, tamaños de arrays, etc)
-
sizeof
-
alignof
-
typeid
- expresión throw
[editar] Expresiones primarias
Los operandos de cualquier operador puede ser otras expresiones o expresiones primarias (p. ej., en 1+2*3, los operandos de operator+ son la subexpresión 2*3 y la expresión primaria 1).
Las expresiones primarias son una de las siguientes:
-
this
; - literales (p. ej., 2 u "Hola, mundo");
- expresiones de identificadores, incluyendo:
- identificadores no calificados adecuadamente declarados (p, ej., n o cout),
- identificadores calificados adecuadamente declarados (p, ej., std::string::npos), y
- identificadores a declarar en declaradores.
(desde C++26) |
(desde C++11) | |
(desde C++17) | |
(desde C++20) |
También se clasifica como expresión primaria cualquier expresión entre paréntesis: esto garantiza que los paréntesis tienen mayor precedencia que cualquier operador. Los paréntesis conservan el valor, tipo, y la categoría de valor.
[editar] Literales
Los literales son tókenes de un programa C++ que representan valores contantes embebidos en el código fuente.
- Los literales de enteros son decimales, octales, hexadecimales o números binarios de tipo entero.
- Los literales de carácter son caracteres individuales de tipo
- char o wchar_t,
|
(desde C++11) |
|
(desde C++20) |
- Los literales de punto flotante son valores de tipo float, double, o long double.
- Los literales cadena son secuencias de caracteres de tipo
- const char[] o const char16_t[],
|
(desde C++11) |
|
(desde C++20) |
- Los literales booleanos son valores del tipo bool, es decir, true y false
|
(desde C++11) |
[editar] 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-inicio-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-entre-llaves-o-igual de la forma
=
cláusula-inicializadora son las expresiones constituyentes de la cláusula-inicializadora.
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 los operandos de E,
|
(desde C++14) |
|
(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. Ten en cuenta que las expresiones que aparecen en el ‘cuerpo de la función’ de las expresiones lambda no son subexpresiones de la expresión lambda. (desde C++11)
Una expresión completa es
- un operando no evaluado,
- una expresión constante,
|
- un declarador de una declaración simple o un inicializador de miembro, incluidas las expresiones constituyentes del inicializador,
- una invocación de un destructor generado al final del tiempo de vida de un objeto que no sea un objeto temporal cuya tiempo de vida no se haya extendido, o
- una expresión que no sea una subexpresión de otra expresión y que no sea parte de una expresión completa.
Si se define una construcción del lenguaje para producir una llamada implícita a una función, el uso de la construcción del lenguaje se considera una expresión para efectos 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 (incluida la evaluación de inicializadores de miembros por defecto de un agregado) (desde C++14) también se considera parte de la expresión completa.
[editar] Expresiones potencialmente evaluadas
Una expresión es potencialmente evaluada a menos que
|
(hasta C++11) | ||
Los siguientes operandos son operandos no evaluados, es decir, no se evalúan:
Una expresión es potencialmente evaluada a menos que
|
(desde C++11) |
Las expresiones potencialmente evaluadas son de uso ODR.
Esta sección está incompleta Razón: ejemplo de operandos no evaluados |
[editar] Expresiones de valor descartado
Una expresión de valor descartado es una expresión que se utiliza solo por sus efectos secundarios. El valor calculado de la expresión se descarta. Dichas expresiones incluyen la expresión completa de cualquier instrucción de expresión, el operando a la izquierda del operador coma integrado, o el operando de una expresión de conversión que convierte al tipo void.
Las conversiones 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 l-valor a r-valor, sin embargo, se aplica, pero solo si la expresión es un gl-valor calificado volatile y tiene una de las formas siguientes (requiere un significado integrado, posiblemente entre paréntesis):
- expresión id,
- expresión de subíndice de array,
- 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 de coma donde el operando derecho es una de estas expresiones.
Si la expresión es un pr-valor no void (después de cualquier conversión de l-valor a r-valor que podría haber tenido lugar), la materialización temporal ocurre.
|
(desde C++17) |
Equivalencia de expresionesVarias expresiones e1, e2, ..., eN son de expresión equivalente si se cumplen todas las condiciones siguientes:
e1 es de expresión equivalente a e2 si y solo si e1 y e2 son de expresión equivalente (lo que significa que e2 también es de expresión equivalente e1). |
(desde C++20) |
[editar] Informes de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 1054 | C++98 | Asignar un valor a una variable volátil podría resultar en una lectura innecesaria debido a la conversión de l-valor a r-valor 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 secuencia de llamadas al destructor en la inicialización de agregado estaba subespecificada. |
Las expresiones completas en la inicialización de agregado están bien especificadas. |
CWG 1383 | C++98 | La lista de expresiones donde la conversión de l-valor a r-valor se aplica a expresiones de valor descartado también cubría los operadores sobrecargados. |
Solo cubre los operadores con significado integrado. |
CWG 1576 | C++11 | Las conversiones de l-valor a r-valor no se aplicaban a expresiones xvalue volátiles de valor descartado. |
Se aplican a la conversión en este caso. |
CWG 2249 | C++98 | Los identificadores que se deben declarar en los declaradores no eran expresiones id. |
Sí 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. |
[editar] Véase también
Documentación de C para Expresiones
|