Si el tipo de retorno de una función es una referencia rvalue, entonces el resultado de la llamada a la función es un valor x; si el tipo de devolución no es de referencia, el resultado de la llamada a la función es un valor pr.
Tanto xvalue como prvalue son valores r, existen algunas pequeñas diferencias entre ellos, más como diferencias entre referencia y no referencia. Por ejemplo, un valor x puede tener un tipo incompleto, mientras que un prvalue generalmente tendrá un tipo completo o tipo vacío. Cuando se aplica typeid a un valor x cuyo tipo es un tipo de clase polimórfica, el resultado se refiere al tipo dinámico; y para prvalue, el resultado se refiere al tipo estático.
Para su declaración declaración T instance = grabStuff<T>();
, si T es un tipo de clase, creo que no hay diferencia entre xvalue y prvalue en este contexto.
El inicializador es un valor r, por lo que el compilador prefiere un constructor de movimiento. Pero si no se declara ningún constructor de movimiento y se declara un constructor de copia con el parámetro de referencia const, entonces se elegirá este constructor de copia y no se producirá ningún error. No sé por qué quieres que esto sea un error. Si esto es un error, cualquier código antiguo será incorrecto cuando copie-inicialice algún objeto de un valor r.
El objeto no necesita ser un objeto global. Un objeto local de gestión de recursos también es un ejemplo (es decir, tal vez: D). – Nawaz
@Kerrek, entonces ¿qué estás diciendo es que esta función solo debe llamarse en temporarios? no se puede asignar el resultado de 'get()' en su ejemplo a una referencia normal de 'Foo &'? – lurscher
@Nawaz: Sí, sí, como dije, depende de usted ... Solo quería dar un ejemplo que sea * not * 'std :: move'. –