C ++: référence const, avant vs après le spécificateur de type

145

Quelle est la différence entre les arguments dans:

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

et

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

? Je ne vois pas ce cas couvert dans la FAQ parashift.

eisbaw
la source
2
est-ce une question de style? "const Fred" sonne bien en anglais, mais "Fred const" me semble mieux.
LatinSuD
1
Sur le même sujet, est - il une raison quelconque il faut préférer Fred const &argplus Fred const& arg? J'aime mieux ce dernier car il const&y a une unité qui signifie "constref", et le nom argest séparé par un blanc de tous les spécificateurs de type.
Frank
4
@dehmann: Mais int const& refne veut pas dire "const ref" mais "ref to const".
Cedric
1
Duplicata de: stackoverflow.com/questions/2640446/…
Michael Aaron Safyan

Réponses:

112

Aucune différence car const est lu de droite à gauche par rapport au &, donc les deux représentent une référence à une instance Fred immuable.

Fred& constsignifierait que la référence elle-même est immuable, ce qui est redondant ; lorsqu'il s'agit de pointeurs const à la fois Fred const*et Fred* constsont valides mais différents.

C'est une question de style, mais je préfère l'utiliser constcomme suffixe car il peut être appliqué de manière cohérente, y compris les fonctions membres const .

Sean Fausett
la source
Ensuite , ce qui est un point de faire std::is_const<const T&>::valueêtre false?
abyss 7
@ abyss.7 c'est une référence à const T; la référence est mutable.
Sean Fausett
125

Comportement

Il n'y a pas de différence sémantique entre const T&et T const&; la langue les traite comme du même type. (La même chose s'applique à const T*et T const*.)

Par souci de style

En ce qui concerne ce que vous devriez préférer stylistiquement, cependant, je ne suis pas d'accord avec beaucoup d'autres réponses et préférerai const T&(et const T*):

  • const T&est le style utilisé dans le livre The C ++ Programming Language de Stroustrup .
  • const T& est le style utilisé dans le standard C ++ lui-même.
  • const T*est le style utilisé dans le livre The C Programming Language de K&R .
  • const T* est le style utilisé dans la norme C.
  • En raison des facteurs ci-dessus, je pense que const T&/ const T*a beaucoup plus d'inertie que T const&/ T const*. const T&/ const T*empiriquement me semble beaucoup plus commun que T const&/ T const*dans tout le code C ++ et C que j'ai vu. Je pense que suivre des pratiques courantes est plus lisible que d'adhérer de manière dogmatique aux règles d'analyse de droite à gauche.
  • Avec T const*, il semble plus facile de l'égarez *comme T* const(surtout si les gens ne sont pas aussi habitués à elle). En revanche, const* Tla syntaxe n'est pas légale.

Qu'en est-il de la règle d'analyse de droite à gauche?

En ce qui concerne tout l'argument d'analyse de droite à gauche que les gens semblent aimer utiliser: comme je l'ai mentionné dans un commentaire à une autre réponse, se const T&lit bien de droite à gauche aussi. C'est une référence à une constante T. «T» et «constant» peuvent chacun fonctionner comme un adjectif ou un nom. (De plus, la lecture de T const*droite à gauche peut être ambiguë car elle pourrait être interprétée à tort comme "pointeur constant vers T" au lieu de "pointeur vers constante T".)

Jamesdlin
la source
3
+1, d'accord. Lors de la lecture de code, il est plus facile de repérer un const si la ligne commence par const. La règle droite-gauche n'est vraiment nécessaire que lors de l'analyse manuelle des déclarations de type poilu. Pourquoi ne pas optimiser pour le cas le plus courant? En outre, à mon humble avis, si vous écrivez des déclarations de type, vous devez exécuter manuellement un FSM dans votre tête, vous le faites mal.
Andreas Magnusson
2
-1. Indépendamment de la justesse de vos conclusions et de la mesure dans laquelle j'y souscris personnellement, elles ne répondent pas directement à la question posée . Cela fait que la deuxième réponse à une question simple ressemble à un charabia hors sujet à propos de certaines machines sous-marines en désordre, sans conclusions, sans réponse directe - rien. Vous obtiendrez mon vote positif lorsque vous ajoutez un simple résumé clair indiquant " Non, il n'y a pas de différence sémantique entre les deux syntaxes , mais il y a quelques considérations stylistiques comme suit ...". Et alors seulement toutes ces balles.
ulidtko
1
OMI la raison se const T&lit mieux, c'est que: 1- Nous lisons le code de gauche à droite. Et 2- Lors de la description d'un nouveau concept, nous partons du concept le plus général vers le plus spécifique. Ici, le constmot-clé est plus général car il coupe l'espace variable en deux catégories, tandis que le spécificateur de type le coupe en plusieurs.
pooya13
"pointer to" doit rester ensemble. Il n'y a donc pas d'ambiguïté pourT const*
Dexter
13

Bien qu'ils soient identiques, pour conserver la cohérence avec la règle DROITE-GAUCHE concernant l'analyse des déclarations C et C ++, il est préférable d'écrireFred const &arg

Référez - vous également à cela pour approfondir votre compréhension des déclarations, des qualificatifs et des déclarateurs.

Chubsdad
la source
1
Je préfère le suffixe, car il fonctionne mieux avec l' typedefexpansion. Exemple: typedef int* pointer;, const pointer n'est pas const int* , il est int* const. La forme du suffixe n'est pas gênante.
Matthieu M.
4
L'OMI const T&lit aussi bien de droite à gauche; c'est une référence à une constante T. Tet constantchacun peut fonctionner comme un adjectif ou un nom.
jamesdlin
7

Les deux fonctionnent, et voici l'explication de l'homme qui l'a écrit.
Pour le citer:

Pourquoi? Quand j'ai inventé "const" (initialement nommé "readonly" et avait un "writeonly" correspondant), je lui ai permis d'aller avant ou après le type parce que je pouvais le faire sans ambiguïté.

Défaut
la source
3

Les références ne fonctionnent pas de la même manière que les pointeurs: pour les pointeurs, vous pouvez avoir 'const pointers' ( type * const p) et 'pointer to const' ( const type * pou type const * p).

Mais vous ne l'avez pas pour les références: une référence fera toujours référence au même objet; en ce sens, vous pouvez considérer que les «références» sont des «références const» (de la même manière que vous pouvez avoir des «pointeurs const»).

Par conséquent, quelque chose comme «type & const ref» n'est pas légal. Vous ne pouvez avoir que «référence au type» ( type &ref) et «référence au type constant» ( const type &refou type const &ref; les deux sont exactement équivalents).

Une dernière chose: même si cela const typesemble plus correct en anglais, l'écriture type constpermet une compréhension plus systématique des déclarations "de droite à gauche": int const & refpeut être lu a 'ref est une référence à une constante int'. Ou un exemple plus compliqué:, int const * const & refref est une référence à un pointeur constant vers une constante int.

Conclusion: dans votre question, les deux sont exactement équivalents.

Cédric H.
la source