Jeśli typ powrotu funkcji jest referencją rvalue, wynikiem wywołania funkcji jest xvalue; jeśli typem zwracanym jest nie-odwołanie, wynikiem wywołania funkcji jest prvalue.
Zarówno wartość x jak i prvalue są wartościami r, istnieją pewne drobne różnice pomiędzy nimi, bardziej przypominają różnice między odniesieniem a brakiem odniesienia. Na przykład wartość x może mieć niekompletny typ, podczas gdy prvalue zwykle ma typ pełny lub typu void. Kiedy typeid zostanie zastosowane do xvalue, której typ jest polimorficznym typem klasy, wynik odnosi się do typu dynamicznego; i dla prvalue, wynik odnosi się do typu statycznego.
Dla twojego oświadczenia deklaracji T instance = grabStuff<T>();
, jeśli T jest typem klasy, myślę, że nie ma różnicy między wartością x a wartością w tym kontekście.
Inicjator jest rwartością, więc kompilator preferuje konstruktor ruchu. Ale jeśli nie zostanie zadeklarowany żaden konstruktor ruchu i zadeklarowany zostanie konstruktor kopiowania z parametrem odwołania, to zostanie wybrany ten konstruktor kopiowania i nie wystąpi błąd. Nie wiem, dlaczego chcesz, żeby to był błąd. Jeśli jest to błąd, każdy stary kod będzie niepoprawny, jeśli zainicjować kopię jakiegoś obiektu z wartości r.
Obiekt nie musi być obiektem globalnym. Przykładem może być również obiekt lokalny zarządzający zasobami (może: D). – Nawaz
@Kerrek, więc mówisz, że ta funkcja powinna być wywoływana tylko w tymczasowych? czy wynik 'get()' w twoim przykładzie nie może być przypisany do normalnego odniesienia 'Foo &'? – lurscher
@Nawaz: Tak, tak jak powiedziałem, to zależy od ciebie ... Chciałem tylko podać przykład, który nie jest '' std :: move'. –