2011-07-07 12 views
6

Tengo un error de compilación extraño al usar el operador de condición.¿Qué más hace el operador de condiciones en C++ por mí?

a,b son int valor, y la siguiente expresión obtiene el error de compilación.

(a>b)?(std::cout << a) : (b=MAX); 
16 (b <unknown operator> 5)' 

(a>b)?(a=MAX) : (std::cout<<b); 
16 (&std::cout)->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>](b)' 

Pero esta expresión funciona bien, lo que es raro ..

(a>b)?(std::cout << a) : (std::cout<<b); 

que no tienen idea de lo que hace una diferencia, y no sé por qué se destacan el error de compilación para. Aquí está mi información gcc:

Reading specs from ./../lib/gcc/mingw32/3.4.2/specs 
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host= 
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable 
-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --e 
nable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-ja 
va-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchroniz 
ation --enable-libstdcxx-debug 
Thread model: win32 
gcc version 3.4.2 (mingw-special)` 
+1

Poner declaraciones con efectos secundarios en una expresión condicional parece bastante feo. ¿Por qué no usar un enunciado if tradicional? –

+0

@Johannes: He marcado tu comentario como no constructivo. ¿Por qué no un comentario que explica por qué no te gusta tanto la pregunta, en lugar de simplemente ser grosero? –

+0

@Brennan Creo que el interlocutor lo sabe muy bien. Traté de solucionarlo editándolo, pero es incomprensible. Nunca he visto un 16 llamado como una función, y nunca he visto un en C++ (y tampoco es un diagnóstico de GCC). Si no formatea su pregunta correctamente, estando en SE por más de un año, debe al menos indicarlo en un formato que permita a otras personas formatearlo. Es por eso que hice -1. Eliminé mi otro comentario porque descubrí que de hecho no es útil. –

Respuesta

14

El operador condicional siempre debe devolver el mismo tipo. En su primer ejemplo,

(a > b) ? (std::cout << a) : (b = MAX); 

la primera rama se obtiene el tipo std::ostream y la segunda rama se obtiene el tipo de b (que es probable que un número entero, dada su contexto). Su segundo ejemplo,

(a > b) ? (std::cout << a) : (std::cout << b); 

no tiene ese problema porque ambas ramas devuelven el mismo tipo, std::ostream. En cualquier caso, probablemente sería más limpio manejar estas condiciones con una simple declaración if - else. El operador condicional tiende a perjudicar la legibilidad y es típicamente sólo es útil cuando condicionalmente asignar a una variable:

int a = (a > b) ? a : b; 
std::cout << a; 
+5

Solo un comentario (porque globalmente, su respuesta está mejor expresada que la mía), pero las reglas para los tipos de 'b' y' c' en 'a? b: c' son un poco más complicados. Básicamente, el compilador debe poder convertir uno de los tipos en el otro.Entonces puede tener 'long' y' int', o 'Base *' y 'Derived *' (pero no 'Derived1 *' y 'Derived2 *'). Alternativamente, una de las expresiones puede ser una expresión 'throw', en cuyo caso, el tipo de la expresión es el otro tipo. –

+0

De hecho, 'void * p = 0; (a> b)? (std :: cout << a): (p = malloc (1)); 'estaría perfectamente bien, por ejemplo. –

+6

Otra forma de arreglar esto es usar el operador de coma: '(a> b)? ((std :: cout << a), a): (b = MAX); 'Esto tiene el beneficio adicional de hacer que el código sea aún más oscuro. ;) –

4

El ?: es un operador en una expresión (o sub-expresión). Una expresión tiene un tipo. ¿Cuál debería ser el tipo de (a > b) ? (std::cout << a) : (b = MAX)? Los tipos en C++ se evalúan estáticamente y no hay manera de que el compilador pueda determinar un tipo común para std::cout << a (tipo std::ostream&) y b = MAX (tipo int).

+0

Sí, la clave aquí es la parte _ "Una expresión tiene un tipo" _. –

2

¿Qué más hace el operador de condiciones en C++ por mí?

Bueno, sí hace coincidir los argumentos segundo y tercero, y eso puede ser muy útil como una forma de extraer tipos de expresiones. Para un artículo alucinante sobre cómo usar esa característica del operador condicional, lea here