2015-05-06 9 views
10

Sono sconcertato da questo:Perché il binding al riferimento const da un ternario crea una copia?

#include <iostream> 
struct X {}; 
void f(const X &x) { std::cerr << &x << "\n"; } 

static X x; 
int main() 
{ 
    f(x); // Off stack address 
    f(false ? X() : x); // Different address on stack. 
} 

Perché sarebbe la seconda invocazione di f fare una copia temporanea?

Modifica: Questa domanda non riguarda tanto il tipo X, quanto il fatto che ne viene fatta una copia. Mi mancava la sottolocazione delle categorie di valori dalla risposta accettata e mi ero aspettato che il parametro di f si legasse su x o X() direttamente come quando riformulava questa come un'istruzione if.

+2

Vedere http://stackoverflow.com/questions/8535226/return-type-of-ternary-conditional-operator –

+2

Vedere: http://stackoverflow.com/questions/8535226/return-type-of-ternary- operatore condizionale – Owbea

+0

La domanda collegata riguardava il fatto di avere tipi diversi su entrambi i lati del colon. Mentre le risposte discutono le categorie di valore, non spiegherebbero direttamente perché la costruzione della copia è necessaria nella domanda che ho chiesto. Ho modificato la mia domanda per chiarirlo. – bking

risposta

9

L'operatore condizionale determina una categoria di tipo e valore comune per il secondo e il terzo operando. Qualunque sia il ramo scelto (come determinato dalla condizione), l'operando corrispondente viene convertito in questa categoria di tipo e valore comune.

In questo caso X() e x entrambi hanno tipo X, quindi il tipo comune è ovviamente X stesso. Ma il risultato è un valore di provalutazione, quindi se si sceglie x (la condizione è falsa), viene applicata la conversione lvalue-rvalue, creando una copia temporanea di valore di x che viene quindi associata al riferimento.

In conclusione, l'uso dell'operatore condizionale stesso è ciò che costringe la copia a essere eseguita.

+0

Giustificazione in standard [* § 5.16 Operatore condizionale *]. – 101010

+0

In questo caso stavo usando C++ 03. Potresti dare una spiegazione sul perché la copia è necessaria lì? Non sarebbe possibile in linea di principio che il compilatore esegua una sorta di 'cast on value category' invece? – bking

+0

@bking C++ 03 ha ancora lvalue e rvalue. Basta sostituire "prvalue" con "rvalue" nella mia risposta. – Brian

Problemi correlati