ternario operador ejemplo c++ types reference conditional-operator lvalue

c++ - ejemplo - operador ternario php



Tipo de retorno de ''?:''(Operador condicional ternario) (3)

El tipo de expresión ternaria ?: Es el tipo común de su segundo y tercer argumento. Si ambos tipos son iguales, obtienes una referencia. Si son convertibles entre sí, uno se elige y el otro se convierte (se promueve en este caso). Como no puede devolver una referencia de valor l a una temporal (la variable convertida / promovida), su tipo es un tipo de valor.

¿Por qué el primero devuelve una referencia?

int x = 1; int y = 2; (x > y ? x : y) = 100;

Mientras que el segundo no lo hace?

int x = 1; long y = 2; (x > y ? x : y) = 100;

En realidad, el segundo no se compiló en absoluto, "no queda el valor de la asignación".


Las expresiones no tienen tipos de retorno, tienen un tipo y, como se conoce en el último estándar de C ++, una categoría de valor.

Una expresión condicional puede ser un lvalue o un rvalue . Esta es su categoría de valor. (Esto es algo así como una simplificación, en C++11 tenemos lvalues, xvalues ​​y prvalues).

En términos muy amplios y simples, un valor de l se refiere a un objeto en la memoria y un valor de r es solo un valor que no necesariamente puede estar asociado a un objeto en la memoria.

Una expresión de asignación asigna un valor a un objeto por lo que la cosa que se asigna debe ser un valor l .

Para que una expresión condicional ( ?: :) Sea un lvalue (nuevamente, en términos amplios y simples), el segundo y tercer operandos deben ser lvalues del mismo tipo . Esto se debe a que la categoría de tipo y valor de una expresión condicional se determina en el momento de la compilación y debe ser apropiada si la condición es verdadera o no. Si uno de los operandos se debe convertir a un tipo diferente para que coincida con el otro, la expresión condicional no puede ser un valor l, ya que el resultado de esta conversión no sería un valor l .

Referencias ISO / IEC 14882: 2011:

3.10 [basic.lval] Lvalues ​​y rvalues ​​(sobre categorías de valor)

5.15 [expr.cond] Operador condicional (reglas para qué tipo y categoría de valor tiene una expresión condicional)

5.17 [expr.ass] Operadores de asignación y asignación compuesta (requisito de que el IHS de una asignación debe ser un lvalor modificable)


No puede devolver un lvalor ya que tendrá que promover implícitamente el tipo de x para que coincida con el tipo de y (ya que ambos lados de : no son del mismo tipo), y con eso tiene que crear un temporal.

¿Qué dice la norma? ( n1905 )

Expresiones 5.17 Operadores de asignación y asignación compuesta

5.17 / 3

Si el segundo y tercer operando tienen tipos diferentes, y cualquiera de los dos tiene un tipo de clase (posiblemente calificado por CV), se intenta convertir cada uno de esos operandos al tipo del otro. El proceso para determinar si una expresión de operador E1 de tipo T1 se puede convertir para que coincida con una expresión de funcionamiento E2 de tipo T2 se define de la siguiente manera:

- Si E2 es un lvalor: E1 se puede convertir para que coincida con E2 si E1 se puede convertir implícitamente (cláusula 4) al tipo "referencia a T2", sujeto a la restricción que en la conversión la referencia debe vincularse directamente (8.5.3 ) a E1.

- Si E2 es un valor r, o si la conversión anterior no se puede realizar:

- si E1 y E2 tienen un tipo de clase, y los tipos de clase subyacentes son iguales o uno es una clase base del otro: E1 se puede convertir para que coincida con E2 si la clase de T2 es del mismo tipo, o una clase base de , la clase de T1, y la calificación cv de T2 es la misma calificación cv que, o una calificación cv mayor que, la calificación cv de T1. Si se aplica la conversión, E1 se cambia a un valor de tipo T2 que aún se refiere al objeto de clase fuente original (o al subobjeto apropiado del mismo). [ Nota: es decir, no se hace ninguna copia. - nota final ] al copiar-inicializar un temporal de tipo T2 de E1 y usar ese temporal como el operando convertido.

De lo contrario (es decir, si E1 o E2 no tienen un tipo de clase, o si ambos tienen tipos de clase pero las clases subyacentes no son las mismas o una clase base de la otra): E1 se puede convertir para que coincida con E2 si E1 puede convertirse implícitamente al tipo que tendría la expresión E2 si E2 se convirtiera a un valor de r (o el tipo que tiene, si E2 es un valor de r).

Usando este proceso, se determina si el segundo operando se puede convertir para que coincida con el tercer operando, y si el tercer operando se puede convertir para que coincida con el segundo operando. Si ambos se pueden convertir, o uno se puede convertir pero la conversión es ambigua, el programa está mal formado. Si ninguno de los dos puede convertirse, los operandos se dejan sin cambios y se realiza una verificación adicional como se describe a continuación. Si es posible exactamente una conversión, esa conversión se aplica al operando elegido y el operando convertido se usa en lugar del operando original por el resto de esta sección.

5.17 / 4

Si el segundo y tercer operandos son lvalues ​​y tienen el mismo tipo, el resultado es de ese tipo y es un lvalue y es un campo de bits si el segundo o el tercer operando es un campo de bits, o si ambos son bits campos.

5.17 / 5

De lo contrario, el resultado es un rvalor. Si el segundo y tercer operandos no tienen el mismo tipo, y cualquiera de los dos tiene un tipo de clase (posiblemente cv calificado), la resolución de sobrecarga se usa para determinar las conversiones (si las hay) que se aplicarán a los operandos (13.3.1.2, 13.6) . Si la resolución de sobrecarga falla, el programa está mal formado. De lo contrario, las conversiones así determinadas se aplican y los operandos convertidos se usan en lugar de los operandos originales para el resto de esta sección.