Se il tipo di ritorno di una funzione è un riferimento di rvalue, il risultato della chiamata di funzione è un valore x; se il tipo di ritorno è non di riferimento, il risultato della chiamata di funzione è un valore di prvalore.
Sia xvalue sia il valore di prvalore sono rvalori, ci sono alcune differenze minori tra di loro, più simili alle differenze tra riferimento e non riferimento. Ad esempio, un xvalue può avere un tipo incompleto, mentre un valore prenuativo deve di solito avere un tipo completo o il tipo void. Quando typeid viene applicato a un valore x il cui tipo è un tipo di classe polimorfico, il risultato si riferisce al tipo dinamico; e per il valore nominale, il risultato si riferisce al tipo statico.
Per la dichiarazione dichiarazione T instance = grabStuff<T>();
, se T è un tipo di classe, penso che non vi sia alcuna differenza tra xvalue e prvalue in questo contesto.
L'inizializzatore è un valore rvalore, quindi il compilatore preferisce un costruttore di movimento. Ma se non viene dichiarato alcun costruttore di movimento, e viene dichiarato un costruttore di copie con parametro const riferimento, verrà scelto questo costruttore di copia e non ci sono errori. Non so perché vuoi che questo sia un errore. Se questo è un errore, qualsiasi vecchio codice sarà errato durante la copia-inizializzazione di alcuni oggetti da un valore rvalue.
L'oggetto non deve essere un oggetto globale. Un oggetto locale che gestisce le risorse è anche un esempio (voglio dire, forse: D). – Nawaz
@Kerrek, quindi quello che stai dicendo è che questa funzione dovrebbe essere chiamata solo nei provvisori? il risultato di 'get()' nel tuo esempio non può essere assegnato ad un riferimento normale di 'Foo &'? – lurscher
@Nawaz: Sì sì, come ho detto, dipende da te ... Volevo solo dare un esempio che * non * 'std :: move' stesso. –