C++ 14 aggiunge una frangia caso in cui le parentesi attorno a un valore di ritorno possono alterare la semantica. Questo snippet di codice mostra due funzioni dichiarate. L'unica differenza è tra parentesi attorno al valore di ritorno.
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
Nei primi func1
restituisce un int
e nel secondo func1
restituisce un int&
. La differenza di semantica è direttamente correlata alle parentesi circostanti.
L'identificatore auto
nella sua forma più recente è stato introdotto in C++ 11. Nella C++ Language Spec è descritto come:
Specifica che il tipo di variabile che viene dichiarata sarà automaticamente dedotto dal suo inizializzatore. Per le funzioni, specifica che il tipo di ritorno è un tipo ritorno trascinamento o sarà dedotto dalle istruzioni return (dal C++ 14)
Oltre C++ 11 introdotto il decltype
specificatore che è descritto nella C++ Language Spec:
ispeziona il tipo dichiarato di un'entità o interroga il tipo restituito di un'espressione.
[snip]
Se l'argomento è il nome di un oggetto unparenthesised/funzione o è un'espressione member (object.member o pointer-> utente registrato), allora il decltype specifica la tipo dichiarato dell'entità specificata da questa espressione.
Se l'argomento è qualunque altra espressione di tipo T, allora
a) se la categoria valore di espressione è xValue, allora il decltype specifica T & &
b) se la categoria valore di espressione lvalue, allora il decltype specifica T &
c) altrimenti, decltype specifica T
.210
[snip]
noti che se il nome di un oggetto viene parentesi tonde, diventa espressione lvalue, così decltype (arg) e decltype ((arg)) sono spesso differenti tipi.
In C++ 14 la possibilità di utilizzare decltype(auto)
stato permesso per i tipi di funzione di ritorno. Gli esempi originali sono dove la differenza semantica con le parentesi entra in gioco. Rivisitare le originali esempi:
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
decltype(auto)
permette il tipo di ritorno finale nella funzione di dedurre dall'entità/espressione return. Nella prima versione return var1;
equivale a restituire il tipo decltype(var1)
(un tipo di ritorno int
dalla precedente regola 1) e nel secondo caso return (var1);
è lo stesso di decltype((var1))
(un tipo di ritorno int &
dalla regola 2b).
Le parentesi restituiscono il tipo int&
anziché int
, quindi una modifica della semantica. Morale della trama - "Non tutte le parentesi su un tipo di reso sono uguali"
Prepararsi per alcuni badge. Stranamente, queste domande * sempre * ottengono il maggior numero di visualizzazioni. –
Benvenuti in Stack Overflow, Jose. Si prega di prendere nota della modifica che ho apportato alla tua domanda. In particolare menziona il cambiamento tra i due blocchi di codice, che salva i lettori dalla frustrazione di dover giocare [individuare la differenza] (http://www.spotthedifference.com/) con il tuo codice. Aiuta anche le persone a riconoscere quando una differenza era intenzionale invece di un semplice errore di battitura (come 'boo'). –
Grazie Rob, hai colto con successo lo spirito della domanda. In Essence mi chiedevo se il compilatore avesse fatto qualcosa di speciale (come provare a valutare prima l'espressione) o se lo ha semplicemente ignorato. –