Pasando int && a f (int &&)

¿Qué está sucediendo exactamente aquí? ¿Por qué es esto un error?

void f(int &&); int && i = 5; f(i); 

¿No es un poco contradictorio?

Espero que sea una referencia rvalue, y así poder pasarlo a f() . Pero me sale un error;

no se conoce conversión de int a int &&

Así que supongo que no es una referencia de valor después de la statement?

Hay una distinción básica aquí entre es y une a . Por ejemplo:

 void f(int &&); 

declara una función que acepta un parámetro que solo se puede inicializar con una referencia de rvalue a (tipo convertible a) int .

 int && i = 5; 

declara un lvalue que solo se puede inicializar con una referencia de rvalue a (tipo convertible a) int . Así, en términos simples,

 f(i); 

intenta pasar una referencia lvalue a un int a una función que acepta solo referencias rvalue a un int . Así que no se comstack.

Para decirle al comstackdor que lance un lvalue a un rvalue, utilizando así constructores de movimiento donde sea aplicable (aunque no en el caso de un int ), puede usar std::move() .

 f(std::move(i)); 

Veo por qué estás confundido. Lo que hay que recordar es que cada vez que tienes un nombre de variable, tienes un valor l .

Así que cuando dices:

 int i = 0; // lvalue (has a name i) 

Y también

 int&& i = 0; // lvalue (has a name i) 

Entonces cuál es la diferencia?

El int&& solo puede vincularse a un valor r así que:

 int n = 0; int i = n; // legal 

PERO

 int n = 0; int&& i = n; // BAD!! n is not an r-value 

sin embargo

 int&& i = 5; // GOOD!! 5 is an r-value 

Entonces, al pasar de i a f() en este ejemplo, estás pasando un valor de l , no un valor de r :

 void f(int &&); int&& i = 5; // i is an l-value f(i); // won't accept l-value 

La situación es en realidad un poco más complicada de lo que he presentado aquí. Si está interesado en una explicación más completa, esta referencia es bastante completa: http://en.cppreference.com/w/cpp/language/value_category

Eso tiene un nombre?
¿Es direccionable?

Si la respuesta a ambas es “sí”, es un L-Valor.

En este fragmento: tengo un nombre, i una dirección (puedes escribir &i ), por lo que es un valor l.

f(&&) obtiene r-value-reference como parámetro, por lo que necesita convertir l-value en r-value reference, lo que se puede hacer con std::move .

 f(std::move(i));