C ++: riferimento const, prima vs dopo l'identificatore di tipo


145

Qual è la differenza tra gli argomenti in:

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

e

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

? Non vedo questo caso nelle FAQ del parashift.



2
è una domanda sullo stile? "const Fred" suona bene in inglese, ma "Fred const" mi sembra migliore.
LatinSuD,

1
In una nota correlata, c'è qualche ragione si dovrebbe preferire Fred const &argsopra Fred const& arg? Mi piace meglio quest'ultimo perché const&c'è un'unità che significa "constref", e il nome argè separato da uno spazio vuoto da tutti gli identificatori di tipo.
Frank,

4
@dehmann: Ma non int const& refsignifica "const ref" ma "ref to const".
Cedric H.,

Risposte:


112

Nessuna differenza come const viene letto da destra a sinistra rispetto a &, quindi entrambi rappresentano un riferimento a un'istanza Fred immutabile.

Fred& constsignificherebbe che il riferimento stesso è immutabile, che è ridondante ; quando si tratta di entrambi i puntatori constFred const* e Fred* constsono validi ma diversi.

È una questione di stile, ma preferisco usarlo constcome suffisso poiché può essere applicato in modo coerente includendo le funzioni dei membri const .


Allora che cosa è un punto di rendere std::is_const<const T&>::valueessere false?
abisso.7

@ abyss.7 è un riferimento a const T; il riferimento è mutabile.
Sean Fausett,

125

Comportamento

Non esiste alcuna differenza semantica tra const T&e T const&; la lingua li considera dello stesso tipo. (La stessa cosa vale per const T*e T const*.)

Per una questione di stile

Riguardo a quale dovresti preferire stilisticamente, tuttavia, dissenzierò da molte altre risposte e preferirò const T&(e const T*):

  • const T&è lo stile usato nel libro Il linguaggio di programmazione di C ++ di Stroustrup .
  • const T& è lo stile utilizzato nello stesso standard C ++.
  • const T*è lo stile usato nel libro The C Programming Language di K&R .
  • const T* è lo stile utilizzato nello standard C.
  • A causa di questi fattori, penso const T&/ const T*abbia molta più inerzia di T const&/ T const*. const T&/ const T*empiricamente mi sembra molto più comune di T const&/ T const*in tutto il codice C ++ e C che ho visto. Penso che seguire le pratiche comuni sia più leggibile che aderire dogmaticamente alle regole di analisi da destra a sinistra.
  • Con T const*, sembra più facile smarrire l' *as T* const(specialmente se le persone non sono così abituate). Al contrario, const* Tnon è sintassi legale.

Che dire della regola di analisi da destra a sinistra?

Per quanto riguarda l'intero argomento di analisi da destra a sinistra che la gente sembra amare usare: come ho già detto in un commento a un'altra risposta, si const T&legge anche da destra a sinistra. È un riferimento a una costante T. "T" e "costante" possono funzionare come aggettivi o nomi. (Inoltre, la lettura da T const*destra a sinistra può essere ambigua poiché potrebbe essere erroneamente interpretata come "puntatore costante a T" anziché come "puntatore a costante T".)


3
+1, concordato. Durante la lettura del codice è più facile individuare una const se la riga inizia con const. La regola di destra è davvero necessaria solo quando si analizzano manualmente le dichiarazioni di tipo particolarmente peloso. Perché non ottimizzare per il caso più comune? Inoltre, IMHO se scrivi dichiarazioni di tipo, quindi devi eseguire manualmente un FSM nella tua testa, lo stai facendo male.
Andreas Magnusson,

2
-1. Indipendentemente da quanto siano giustificate le tue conclusioni e da quanto io personalmente accetto, non rispondono direttamente alla domanda . Questo fa apparire la seconda risposta a una semplice domanda come un gorgogliante fuori tema su alcune macchine sottomarine disordinate, senza conclusioni, senza risposta diretta - niente. Otterrai il mio voto quando aggiungi un semplice riassunto chiaro affermando " No, non c'è differenza semantica tra entrambe le sintassi , ma ci sono alcune considerazioni stilistiche come segue ...". E solo allora tutti quei proiettili.
Ulidtko,

1
IMO la ragione è const T&migliore, è che: 1- Leggiamo il codice da sinistra a destra. E 2- Nel descrivere un nuovo concetto partiamo dal concetto più generale a quello più specifico. Qui, la constparola chiave è più generale in quanto suddivide lo spazio variabile in due categorie, mentre l'identificatore di tipo lo suddivide in molte categorie.
pooya13

"puntatore a" dovrebbe rimanere insieme. Quindi non c'è ambiguità perT const*
Dexter

13

Sebbene siano la stessa cosa, per mantenere la coerenza con la regola DESTRA-SINISTRA sull'analisi delle dichiarazioni C e C ++, è meglio scrivereFred const &arg

Fare riferimento anche a questo per sviluppare una maggiore comprensione di dichiarazioni, qualificatori e dichiaratori.


1
Preferisco il suffisso, perché funziona meglio con l' typedefespansione. Esempio: typedef int* pointer;, const pointer non è const int* , è int* const. La forma del suffisso non è imbarazzante.
Matthieu M.,

4
Anche l'IMO const T&legge bene da destra a sinistra; è un riferimento a una costante T. Te constantognuno può funzionare come un aggettivo o un sostantivo.
jamesdlin,

7

Entrambi funzionano e ecco la spiegazione dell'uomo che l'ha scritto.
Per citarlo:

Perché? Quando ho inventato "const" (inizialmente chiamato "readonly" e avevo un corrispondente "writeonly"), ho permesso che andasse prima o dopo il tipo perché potevo farlo senza ambiguità.




3

I riferimenti non funzionano allo stesso modo dei puntatori: per i puntatori è possibile avere "puntatori const" ( type * const p) e "puntatore a const" ( const type * po type const * p).

Ma non hai questo per i riferimenti: un riferimento farà sempre riferimento allo stesso oggetto; in tal senso puoi considerare che i "riferimenti" sono "riferimenti costanti" (allo stesso modo in cui puoi avere "puntatori const").

Pertanto qualcosa come 'type & const ref' non è legale. Puoi avere solo 'riferimento a tipo' ( type &ref) e 'riferimento a tipo costante' ( const type &refotype const &ref ; entrambi sono esattamente equivalenti).

Un'ultima cosa: anche se const typesembra più corretto in inglese, la scrittura type constconsente una comprensione più sistematica delle dichiarazioni "da destra a sinistra": int const & refpuò essere letta se "ref è un riferimento a un int costante". O esempio più complicato: int const * const & refref è un riferimento a un puntatore costante a un int costante.

Conclusione: nella tua domanda, entrambi sono esattamente equivalenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.