C ++: const Referenz, vor vs nach Typspezifizierer

144

Was ist der Unterschied zwischen den Argumenten in:

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

und

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

? Ich sehe diesen Fall nicht in den Parashift-FAQ.

Eisbaw
quelle
2
Ist das eine Frage zum Stil? "const Fred" klingt gut in Englisch, aber "Fred const" sieht für mich besser aus.
LatinSuD
1
Über einen entsprechenden Hinweis, gibt es keinen Grund vorziehen sollte Fred const &argüber Fred const& arg? Letzteres gefällt mir besser, weil const&es dort eine Einheit gibt, die "constref" bedeutet, und der Name argdurch ein Leerzeichen von allen Typspezifizierern getrennt ist.
Frank
4
@dehmann: Aber int const& refnicht "const ref", sondern "ref to const".
Cedric H.
1
Duplikat von: stackoverflow.com/questions/2640446/…
Michael Aaron Safyan

Antworten:

112

Kein Unterschied, da const in Bezug auf das & von rechts nach links gelesen wird, sodass beide einen Verweis auf eine unveränderliche Fred-Instanz darstellen.

Fred& constwürde bedeuten, dass die Referenz selbst unveränderlich ist, was redundant ist ; beim Umgang mit const Zeigern sind beide Fred const*und Fred* constgültig aber unterschiedlich.

Es ist eine Frage des Stils, aber ich bevorzuge die Verwendung constals Suffix, da es konsistent angewendet werden kann, einschließlich konstanter Elementfunktionen .

Sean Fausett
quelle
Was ist dann ein Punkt zu std::is_const<const T&>::valuesein false?
Abgrund.7
@ abyss.7 das ist ein Verweis auf const T; Die Referenz ist veränderlich.
Sean Fausett
125

Verhalten

Es gibt keinen semantischen Unterschied zwischen const T&und T const&; Die Sprache behandelt sie als denselben Typ. (Gleiches gilt für const T*und T const*.)

Aus Stilgründen

In Bezug darauf, was Sie stilistisch bevorzugen sollten, werde ich jedoch von vielen anderen Antworten abweichen und const T&(und const T*) bevorzugen :

  • const T&ist der Stil, der in Stroustrups Buch The C ++ Programming Language verwendet wird .
  • const T& ist der Stil, der im C ++ - Standard selbst verwendet wird.
  • const T*ist der Stil, der in K & Rs Buch The C Programming Language verwendet wird .
  • const T* ist der im C-Standard verwendete Stil.
  • Aufgrund der oben genannten Faktoren denke ich const T&/ const T*habe viel mehr Trägheit als T const&/ T const*. const T&/ const T*scheint mir empirisch weitaus häufiger zu sein als T const&/ T const*in all dem C ++ - und C-Code, den ich gesehen habe. Ich denke, dass es besser ist, gängigen Praktiken zu folgen, als sich dogmatisch an die Parsing-Regeln von rechts nach links zu halten.
  • Mit T const*scheint es leichter zu verlegen die *als T* const(vor allem , wenn die Menschen nicht so daran gewöhnt). Im Gegensatz dazu const* Tist keine legale Syntax.

Was ist mit der Parsing-Regel von rechts nach links?

In Bezug auf das gesamte Parsing-Argument von rechts nach links, das die Leute gerne zu verwenden scheinen: Wie ich in einem Kommentar zu einer anderen Antwort erwähnt habe, const T&liest es sich auch gut von rechts nach links. Es ist eine Referenz auf eine T-Konstante. "T" und "Konstante" können jeweils als Adjektiv oder Substantiv fungieren. (Außerdem kann das Lesen von T const*rechts nach links mehrdeutig sein, da es fälschlicherweise als "Zeigerkonstante auf T" anstatt als "Zeiger auf Konstante T" interpretiert werden kann .)

Jamesdlin
quelle
3
+1, vereinbart. Beim Lesen von Code ist es einfacher, eine Konstante zu erkennen, wenn die Zeile mit Konstante beginnt. Die Rechts-Links-Regel wird wirklich nur benötigt, wenn besonders haarige Typdeklarationen manuell analysiert werden. Warum nicht für den häufigsten Fall optimieren? Außerdem, IMHO, wenn Sie Typdeklarationen schreiben, so dass Sie einen FSM manuell in Ihrem Kopf ausführen müssen, machen Sie es falsch.
Andreas Magnusson
2
-1. Unabhängig davon, wie gerechtfertigt Ihre Schlussfolgerungen sind und wie sehr ich ihnen persönlich zustimme, beantworten sie die gestellte Frage nicht direkt. Dies lässt die zweithäufigste Antwort auf eine einfache Frage wie einen nicht themenbezogenen Kauderwelsch über eine unordentliche Unterwassermaschine erscheinen, ohne Schlussfolgerungen, ohne direkte Antwort - nichts. Sie erhalten meine Gegenstimme, wenn Sie eine einfache, klare Zusammenfassung hinzufügen, die besagt: " Nein, es gibt keinen semantischen Unterschied zwischen beiden Syntaxen , aber es gibt einige stilistische Überlegungen wie folgt ...". Und nur dann all diese Kugeln.
Ulidtko
1
IMO const T&lautet der Grund besser: 1- Wir lesen Code von links nach rechts. Und 2- Wenn wir ein neues Konzept beschreiben, gehen wir vom allgemeineren zum spezifischeren Konzept über. Hier ist das constSchlüsselwort allgemeiner, da es den Variablenraum in zwei Kategorien unterteilt, während der Typspezifizierer ihn in viele Kategorien unterteilt.
Pooya13
"Zeiger auf" sollte zusammen bleiben. Es gibt also keine Unklarheiten fürT const*
Dexter
13

Obwohl sie ein und dasselbe sind, ist es besser zu schreiben , um die Konsistenz mit der RECHTS-LINKS- Regel zum Parsen von C- und C ++ - Deklarationen zu gewährleistenFred const &arg

Lesen Sie dies auch, um mehr Verständnis für Deklarationen, Qualifizierer und Deklaratoren zu entwickeln.

Chubsdad
quelle
1
Ich bevorzuge das Suffix, weil es mit der typedefErweiterung besser funktioniert . Beispiel: typedef int* pointer;, const pointer ist nicht const int* , es ist int* const. Die Suffixform ist nicht umständlich.
Matthieu M.
4
IMO const T&liest auch von rechts nach links gut; es ist eine Referenz auf eine T-Konstante. Tund constantjeder kann als Adjektiv oder Substantiv arbeiten.
Jamesdlin
7

Beide funktionieren, und hier ist die Erklärung des Mannes, der sie geschrieben hat.
Um ihn zu zitieren:

Warum? Als ich "const" erfand (ursprünglich "readonly" genannt und hatte ein entsprechendes "writeonly"), ließ ich es vor oder nach dem Typ gehen, weil ich dies ohne Mehrdeutigkeit tun konnte.

Standard
quelle
3

Referenzen funktionieren nicht wie Zeiger: Für Zeiger können Sie 'const pointers' ( type * const p) und 'pointer to const' ( const type * poder type const * p) haben.

Für Referenzen haben Sie dies jedoch nicht: Eine Referenz bezieht sich immer auf dasselbe Objekt. In diesem Sinne können Sie davon ausgehen, dass 'Referenzen' 'Konstantenreferenzen' sind (genauso wie Sie 'Konstantenzeiger' haben können).

Daher ist so etwas wie 'type & const ref' nicht legal. Sie können nur 'Verweis auf Typ' ( type &ref) und 'Verweis auf konstanten Typ' haben ( const type &refoder type const &ref; beide sind genau gleichwertig).

Eine letzte Sache: Auch wenn const typedas auf Englisch korrekter klingt, type constermöglicht das Schreiben ein systematischeres Verständnis der Deklarationen "von rechts nach links": int const & refKann gelesen werden, hat 'ref ist ein Verweis auf eine Konstante int'. Oder komplizierteres Beispiel: int const * const & refref ist eine Referenz auf einen konstanten Zeiger auf eine Konstante int.

Fazit: In Ihrer Frage sind beide genau gleichwertig.

Cedric H.
quelle