C ++: referencia de referencia, antes vs después del especificador de tipo

Cuál es la diferencia entre los argumentos en:

int foo1(const Fred &arg) { ... } 

y

 int foo2(Fred const &arg) { ... } 

? No veo este caso cubierto en las Preguntas frecuentes sobre parashift.

No hay diferencia ya que const se lee de derecha a izquierda con respecto a &, de modo que ambos representan una referencia a una instancia de Fred inmutable.

Fred& const significa que la referencia en sí es inmutable, lo que es redundante ; Cuando se trata de punteros const, tanto Fred const* como Fred* const son válidos pero diferentes.

Es una cuestión de estilo, pero prefiero utilizar const como sufijo, ya que se puede aplicar de forma consistente, incluidas las funciones miembro de const .

Comportamiento

No hay diferencia semántica entre const T& y T const& (ni entre const T* y T const* ); el idioma los trata como del mismo tipo.

Como una cuestión de estilo

Sin embargo, en cuanto a lo que deberíais preferir estilísticamente, disentiré de muchas de las otras respuestas y preferiría const T& (y const T* ):

  • const T& es el estilo utilizado en el libro The C ++ Programming Language de Stroustrup.
  • const T& es el estilo utilizado en el estándar C ++ en sí mismo.
  • const T* es el estilo utilizado en el libro The C Programming Language de K & R.
  • const T* es el estilo utilizado en el estándar C.
  • Debido a los factores anteriores, creo que const T& / const T* tiene mucha más inercia que T const& / T const* . const T& / const T* empíricamente parece mucho más común para mí que T const& / T const* en todos los códigos C ++ y C que he visto. Creo que seguir las prácticas comunes es más legible que adhirir dogmáticamente a las reglas de análisis de derecha a izquierda.
  • Con T const* , parece más fácil perder el * como T* const (especialmente si las personas no están tan acostumbradas a él). Por el contrario, const* T no es una syntax legal.

¿Qué pasa con la regla de análisis de derecha a izquierda?

Con respecto a todo el argumento de análisis de derecha a izquierda que a la gente parece gustarle usar: como mencioné en un comentario a otra respuesta, const T& lee bien de derecha a izquierda también. Es una referencia a una constante T. “T” y “constante” cada uno puede funcionar como un adjetivo o un sustantivo. (Además, leer T const* derecha a izquierda puede ser ambiguo ya que podría interpretarse incorrectamente como “constante de puntero a T” en lugar de “puntero a T constante”).

Aunque son una y la misma, para mantener la coherencia con la regla DERECHA-IZQUIERDA sobre el análisis de declaraciones C y C ++, es mejor escribir Fred const &arg

También refiérase esto para desarrollar más entendimiento sobre declaraciones, calificadores y declaradores.

No hay diferencia, ambos son sintáctica y semánticamente iguales.

Ambos funcionan, y aquí está la explicación del hombre que la escribió.
Para citarlo:

¿Por qué? Cuando inventé “const” (inicialmente llamado “readonly” y tenía una correspondiente “writeonly”), permití que fuera antes o después del tipo porque podía hacerlo sin ambigüedad.

Las referencias no funcionan de la misma manera que los punteros: para los punteros puede tener ‘punteros const’ ( type * const p ) y ‘puntero a const’ ( const type * p o type const * p ).

Pero no tiene esto para referencias: una referencia siempre se referirá al mismo objeto; en ese sentido, puede considerar que las “referencias” son “referencias const” (de la misma manera que puede tener “const punteros”).

Por lo tanto, algo como ‘type & const ref’ no es legal. Solo puede tener ‘referencia al tipo’ ( type &ref ) y ‘referencia al tipo constante’ ( const type &ref type const &ref o type const &ref ; ambos son exactamente equivalentes).

Una última cosa: incluso si el const type suena más correcto en inglés, escribir type const permite una comprensión más sistemática de las declaraciones “de derecha a izquierda”: int const & ref se puede leer tiene ‘ref es una referencia a una constante int’. O un ejemplo más complicado: int const * const & ref , ref es una referencia a un puntero constante a una constante int.

Conclusión: en su pregunta, ambos son exactamente equivalentes.