2011-07-13 13 views
8

duplicados posibles:
&&= and ||= operators¿Por qué no hay operador || = en C/C++?

Véase el título. Esta pregunta puede ampliarse para incluir todos los operadores lógicos + de asignación. Para aclarar: no estoy hablando del operador | =.

Otro ejemplo: & & =

Gracias.

Ejemplo:

 
bool result = false; 

// Today 
result = result || my_test1(); 
// Do stuff 
result = result || my_test2(); 

// In my imagination only... 
result ||= my_test1(); 
// Do stuff 
result ||= my_test2(); 
+0

¿Cuál sería exactamente el caso de uso para un operador de este tipo? – RedX

+0

Hay _are_ operadores para tal construcción (raramente, si alguna vez, es necesaria). La sintaxis es '| = !!' y '& = !!', respectivamente. Si ese es el código que le gustaría escribir es una pregunta diferente (aunque debo admitir que he utilizado al menos la expresión '!!' unas cuantas veces antes, y la 'probable' macro en las fuentes del kernel de Linux también lo usa). – Damon

+7

@Damon: '| = !!' no es un operador, es una combinación de tres operadores: '| =! ! 'y la alta precedencia de'! 'lleva a problemas si tiene una expresión con menor precedencia, como' + 'en el lado derecho, e. gramo. 'x | = !! 5 + x' le dará 'x | = 1 + x'. – hirschhornsalz

Respuesta

13

En una conjetura, ya que sólo tendría sentido para Bools, que eran tarde a la fiesta

Incluso si Bools habían existido en el inicio de estos operadores serían de uso limitado, ya que sin efectos secundarios serían idénticos a |= y &= con operandos booleanos, por lo que el único uso sería atrapar pasando un no bool por accidente.

Si los operadores propuestos son también cortocircuitos (no excesivo como || y && son para este tipo incorporado), entonces también tiene una justificación adicional para ellos en la presencia de efectos secundarios.

La única otra posible razón que puedo pensar para permitirlos sería si simplificara significativamente el análisis/compilación del lenguaje, sin embargo, probablemente no sea el caso dado que no tienen sentido para los tipos que no son bool.

En última instancia, no están en el idioma porque nadie se ha preocupado lo suficiente como para ponerlos en el idioma, por lo que podemos concluir que ninguna de estas justificaciones es suficiente para justificar el costo de presentar una propuesta, implementando la característica.

+7

"ya que serían idénticos a | = y & =" no, no serían lo mismo. bool a = verdadero; a || = somecomplexfuncReturningBoolAfterAnHour() – josefx

+0

"el único uso sería atrapar pasando por accidente un no bool" ... eso implica que el uso no es una justificación suficiente, pero en mi humilde opinión es suficiente. Además, te has perdido el hecho de que && y || son operaciones de cortocircuito, y si el lenguaje proporciona un cortocircuito '|| =' y '&& =' serían potencialmente más eficientes -y utilizables a pesar de posibles problemas de punteros nulos, etc.- que absolver '| =' y '& = 'para el mismo código. –

+2

Habría votado, si la respuesta hubiera consistido en la primera oración solamente. '&& =' tiene tanto sentido como '&&': '3 && 4' es verdadero, mientras que' 3 & 4' es falso. – soulmerge

8

Porque no tendrían sentido. La definición de x op= y es x = x op y, excepto que x solo se evalúa una vez. ¿Qué significa esto con un operador en cortocircuito, que convierte cada uno de sus operandos (si los evalúa) en bool? El equivalente de ||= podría ser algo como:

if (!x) 
    x = y; 

que es ciertamente diferente de la interpretación de otra op=.

+0

¡Prácticamente has contrarrestado tu declaración de apertura! :-) La operación de cortocircuito de los builtins es una observación aguda, y el equivalente propuesto me da sentido para los tipos integrados. De acuerdo con el comportamiento de C++ para los tipos definidos por el usuario, es de esperar que el operador '&& = (bool rhs)' explícitamente definido por el usuario no sea un cortocircuito. Es todo un poco raro, pero está de acuerdo con lo que C++ hace ahora ... si se lo propusiera para un futuro estándar de C++, no puedo imaginar a nadie que se oponga seriamente a que "no tendría sentido". –

+0

@Tony Proponlo, entonces. Mi declaración de apertura puede haber sido demasiado general: los operadores op= no pueden tener el mismo sentido que los operadores convencionales op=; la definición para ellos debería ser diferente si queremos mantener un cortocircuito. (Por otro lado, el usuario define '||' y '&&' no cortocircuito, entonces hay un precedente para dejarlo. Un precedente malo, en mi humilde opinión) –

+1

Mi razonamiento (no importa si x se evalúa una vez * si es posible * o no) sería que dado que "a = a && b" es perfectamente pensable y utilizable, entonces "a && = b" también podría darse; por lo tanto, creo que es solo porque están "retrasados" como respondió otro usuario. – ShinTakezou

3

No hay una buena razón lógica ... solo presiones históricas para las características.

Los operadores lógicos no están normalmente disponibles como códigos de operación de una sola CPU, por lo que no son tan baratos o fundamentales como sus contrapartes bit a bit. Un XOR lógico sería bueno también, quizás ^^, luego ^^=.

Aún así, la proliferación de operadores hace que sea cada vez más doloroso crear tipos definidos por el usuario con una semántica integrada, y hay pocas ganancias en el mundo real. Todavía me gustaría verlos; estos operadores existen en algunos otros idiomas, como Ruby, y los he encontrado prácticos y expresivos.

+1

+1 la "razón lógica no válida ..." me parece la explicación más lógica, aunque el seguimiento de los códigos de operación de la CPU no me convence totalmente (la CPU puede estar "configurada en condición" y los operadores bit a bit en enteros que son solo 1 o 0 se comportan como operadores lógicos) – ShinTakezou

+0

@ShinTakezou: "establecer en condición" puede facilitar el mapeo de enteros a booleanos, pero si tiene dos registros o ubicación de memoria con enteros y necesita primero "probarlos" para establecer las condiciones luego usa esa condición para generar un valor booleano "estándar" 0 versus 1, luego aplica el operador bit a bit; tienes más pasos. Algo parecido a 'o regA, regA // establece condiciones; set0ifz_1ifnz regA; 'antes de que pueda hacer una operación bit a bit. El "set0ifz_1ifnz" podría no estar disponible como un solo código de operación tampoco. –

+0

Estoy de acuerdo, pero también supongo que estos "límites" de la CPU no pueden afectar la sintaxis actual de los lenguajes modernos, si se considera útil tener tal sintaxis, por supuesto; los compiladores pueden optimizar mucho el código producido, sin importar cómo se ve la fuente (por ejemplo, "a ++" de C contra "a = a + 1" de otros idiomas puede producir el mismo código) – ShinTakezou

3

Porque su modus operandi es muy diferente.

mirada a las firmas: existen

operadores
T operator+(T,T); 
T& T::operator+=(T); 

T operator*(T,T); 
T& T::operator*=(T); 

bool operator&&(T,T); 
??? 

compuestos para los operadores que devuelven el mismo tipo de argumento, los && y || operadores devuelven un valor booleano (o al menos, se espera que a), y por lo tanto no tiene sentido crear una versión compuesta, excepto quizás para booleanos solo.

+0

Nunca lo he intentado, pero supongo también "floatA & floatB" no tiene mucho sentido, aunque el resultado puede ser, formalmente, un floatC; más aún, especialmente en C, donde no hay un tipo de bool primitivo, y podemos usar un int para él; entonces, si "doubleA & = floatB" es posible, incluso "a && = b" debería ser, creo. – ShinTakezou

+0

"' &&, || y^'operadores devuelven un booleano" ... no, '^' es un operador bit a bit, que esto no se conoce universalmente podría ser porque se pueden aplicar a booleanos con cierto éxito, aunque es arriesgado. Además, esto supone que estás hablando de sobrecarga de C++, pero no explica por qué los compiladores de C y C++ no proporcionan esas operaciones para los booleanos incorporados reales. –

+0

@ShinTakezou: No hay 'bool' pero todos tienen un' bool' typedef'ed y hay una noción de contexto booleano para las condiciones @Tony: a la derecha para '^', resbalé. No estaba hablando (no realmente) sobre la sobrecarga del operador, solo necesitaba exponer las firmas para mostrar la diferencia. –