2011-05-22 20 views
10

Definido de esta manera, no podemos hacer ni ++x++ ni ++x--. Pero, por otro lado, tanto (++x)++ y (++x)-- son expresiones útiles: (++x)++ incrementos x por dos y devuelve el valor "en el medio", mientras que (++x)-- es esencialmente equivalente a x+1 pero completamente evita tener que llamar operator+, que puede ser muy útil a veces .¿Por qué el operador postfix ++ tiene mayor prioridad que el operador prefijo ++?

¿Por qué la precedencia no está definida para tener ++x++ expandirse automáticamente a (++x)++ en lugar de ++(x++)? ¿Hay algún significado oculto para este último que no entiendo, o es simplemente para mantener la prioridad de una lista simple con todos los operadores de prefijo que componen un solo nivel?

EDITAR Ok, yo no he dicho explícitamente, pero: por supuesto que quería decir x a ser de tipo definido por el usuario. Para tipos incorporados, (x+=2)-1 es, por supuesto, mejor que (++x)++, y x+1 es un lote mejor que (++x)--. La situación que tengo en mente es un iterador a un tipo bastante complicado de contenedor semi-asociativo, donde los operadores += y + (que están diseñados para acceso aleatorio) tienen que reconstruir un caché para trabajar eficientemente para solicitudes generales, y por lo tanto un orden de magnitud más lento que ++. Pero, por supuesto, puedo modificarlos para verificar siempre primero si el argumento es un número entero muy pequeño, y en ese caso simplemente llame al operator++ repetidamente en lugar de hacer el procedimiento de acceso aleatorio. Eso debería funcionar bien aquí, aunque podría imaginar que en algún momento podría tener una situación en la que quiero que operator+= vaya siempre al modo de acceso aleatorio, independientemente de la cantidad de números que presente.


Así que ... para mí, llego a la conclusión que la respuesta es:

la ventaja de tener una lista de precedencia simple y bien memorizeable en el que todos los operadores de sufijo se presentan ante cualquier de los operadores de prefijo es suficiente para tolerar el inconveniente menor de tener que usar siempre paréntesis para componer operadores de pre y postfix ++/--, ya que esta composición se usa muy pocas veces.

El más simple "C hace de esta manera", aunque parece probable que sea el verdadera razón, es mucho menos satisfactoria para mí, porque desde ++x++ no se le permitió en absoluto en C que lo haría ha sido posible redefinir esta misma composición sin dañar ningún código existente.

De todos modos, seguiré usando (++x)--, ya que los paréntesis realmente no duelen demasiado.

+3

incluso si estos ejemplos no fueran ubicos, habría poca utilidad debido a la gran posibilidad de confusión –

+0

ambos no son UB en C++ 0x –

+0

¿Tiene algo que decir la especificación C original sobre cómo se agrupan esos operadores? ? –

Respuesta

4

C++ estándar simplemente mantuvo las reglas C y obviamente no se corrigieron, considerando la sobrecarga de operadores y las expresiones idiomáticas que aún se inventan en un lenguaje aún por inventar.

En cuanto a lo que está disponible en D.M. Ritchie Home Page, en ver que esta preferencia está ya presente en B (operadores unarios están obligados derecha a izquierda. Por lo tanto -!x++ está obligado -(!(x++)) en referencia Usuarios a B) y yo no No veo operadores de incremento en BCPL.

1

Ambos (++x)++ y (++x)-- invocan undefined behaviour [asumiendo que x es un tipo primitivo]. Para el usuario definido, escriba el escenario would be different. Sin embargo, generalmente no se recomienda utilizar expresiones confusas en su código.

Por lo que respecta a la precencia this answer explica por qué el incremento de publicación tiene una precedencia mayor que el incremento previo.

+3

Como el tipo de 'x' no se ha especificado en la pregunta, ninguno de estos arroja necesariamente un comportamiento indefinido. –

+1

Por cierto, leí la publicación de Eric del enlace que publicaste, y no explica nada. También la pregunta en ese enlace está etiquetada con 'C#'. C# no es lo mismo que C++. No entiendo la relevancia de la publicación de Eric aquí. – Nawaz

+0

@Nawaz: Su razón parece apropiada desde el punto de vista de C++ también. –

6

(++x)++ incrementos x por dos y devuelve el valor "en el medio"

Por qué no (x += 2) - 1 o (++x, x++)? Ambos parecen ser más claros. Para los escalares, ambos están bien definidos también en C++ 03, a diferencia de la expresión propuesta.


(++x)-- es esencialmente equivalente a x+1 pero completamente evita tener que llamar operator+, que puede ser bastante útil a veces.

Esa es una afirmación arbitraria sin ninguna explicación. Así que voy a tirar a la piscina:

x+1 es esencialmente equivalente a (++x)-- pero completamente evita tener que llamar operator++ y operator-- que puede ser útil a veces.


¿Por qué es la precedencia no se define para tener ++ ++ x expande automáticamente a (x ++) ++ ++ en lugar de (x ++)

sólo para hacer tales casos de esquina arcanos no error fuera? De ninguna manera. ¿Puedes recitar man operator por mí? Si no puede hacer eso, mejor no intente y escriba ++x++ en su código.

Cuestiones relacionadas