2012-04-17 11 views
9

Ho questo codice (versione semplificata):Un riferimento associato a un parametro di funzione prolungherà la durata di tale temporaneo?

const int& function(const int& param) 
{ 
    return param; 
} 

const int& reference = function(10); 
//use reference 

Non riesco decidere in che misura C++ 03 standard $ 12.2/5 formulazione

La temporanea in cui il riferimento è legato o il temporaneo che è l'oggetto completo di un suboggetti di cui il temporaneo è legato persiste per la durata del riferimento ...

è applicabile qui.

È la variabile reference nel codice sopra valido o pendente? Il riferimento nel codice chiamante prolungherà la durata del passaggio temporaneo come parametro?

risposta

9

A a piena espressione è un'espressione che non è una sottoespressione di un'altra espressione. In questo caso, l'intero espressione contenente la chiamata function(10) è l'espressione di assegnamento:

const int& reference = function(10); 

Per chiamare function con l'argomento 10, un oggetto const riferimento temporaneo viene creato all'oggetto intero temporaneo 10. La durata del numero intero temporaneo e il riferimento const-temporaneo si estendono attraverso l'assegnazione, quindi sebbene l'espressione di assegnazione sia valida, il tentativo di utilizzare il numero intero a cui fa riferimento reference è Undefined Behaviour come reference non fa più riferimento a un oggetto live.

Il C++ 11 standard, credo, chiarisce la situazione:

La temporanea a cui è legato il riferimento o la temporanea che è l'oggetto completo di un oggetto secondario a cui è legato il riferimento persiste per tutta la durata del riferimento eccezione:

...

- un temporaneo legato a un parametro di riferimento in una chiamata di funzione (5.2.2) persiste fino al completamento del full-espressione contenente la chiamata.

EDIT: "La temporanea a cui è legato il riferimento ... persiste per tutta la durata del riferimento". In questo caso, la durata del riferimento termina alla fine dell'espressione di assegnazione, così come la durata dell'intero temporaneo.

2

Questo verrà compilato, ma si finirà con un riferimento ciondolante. param viene liberato dopo i ritorni function.

  1. funzione viene chiamata con un riferimento, oggetto anonimo temporanea
  2. funzione restituisce il riferimento
  3. ora che la funzione è tornato il parametro temporaneo è rilasciato
  4. il riferimento è ora penzolava come l'oggetto era distrutto

Se lo si fosse reso non const, non sarebbe stato compilato perché non si può passare un riferimento non const a un oggetto anonimo.

+0

Non viene 'param' distrutto alla fine del compito? "Gli oggetti temporanei vengono distrutti come ultimo passaggio nella valutazione dell'espressione completa (1.9) che (lessicamente) contiene il punto in cui sono stati creati." –

1

è questa parte che è importante

La temporanea in cui è tenuto il riferimento

In questo caso il parametro è legato alla temporanea, e verranno distrutti dopo la chiamata.

Non è possibile prolungare ulteriormente la durata passando il riferimento su.

+1

Non si può negare che il suo 'riferimento' è legato al temporaneo. Esistono infatti diversi riferimenti legati al provvisorio. Lo standard è molto mal scritto qui. L'intento è, ovviamente, che la durata sia estesa solo per corrispondere al riferimento inizializzato con il provvisorio reale. Purtroppo, non è proprio quello che dice lo standard. –

+2

@JamesKanze: Sono d'accordo sul fatto che la formulazione non sia molto precisa, ma detto questo, con un modello di compilazione separato, sarebbe impossibile per il compilatore sapere che la durata del temporaneo dovrebbe essere estesa al sito di chiamata dopo la funzione completa. Il compilatore non può sapere se il riferimento restituito è legato allo stesso oggetto del parametro o qualsiasi altro oggetto (es. 'Const int & function (const int &) {statico int i = 0; return i;}') –

+0

Questa risposta non è t indirizzo nulla ... e il temporaneo viene distrutto al punto e virgola alla fine della dichiarazione, non immediatamente dopo la chiamata. – Potatoswatter

2

Dalla C++ 11 viepoint un riferimento restituito da una funzione è non una temporanea:

12.12.1 Temporaries di tipo classe vengono creati in diversi contesti: binding un riferimento a un prvalue (8.5.3), restituendo un valore di prvalore (6.6.3), una conversione che crea un valore di prvalore (4.1, 5.2.9, 5.2.11, 5.4), generando un'eccezione (15.1), inserendo un gestore (15.3), e in alcune inizializzazioni (8.5).

Una funzione che restituisce un valore di riferimento non restituito ("valore puro"), quindi non è un valore temporaneo. Questo sembra del tutto naturale: compilatore non può gestire la vita di oggetti di riferimento, è responsabilità del programmatore

Così, il compilatore non fornisce alcun guarantes liftime per const int & di riferimento dal momento che non è delimitata a temporanea.

+0

... e questo è un punto in cui C++ 11 ha fissato una formulazione ambigua di C++ 03, una correzione da applicare retroattivamente. – Potatoswatter

Problemi correlati