How is it possible to get a reference to an rvalue?
Conceptually, an rvalue expression creates a temporary object, or sometimes denotes an existing object. That can be bound to a reference like any other object; but, to avoid confusion, the language only allows that for rvalue and const
lvalue references.
I have used std::move and std::forward in C++. My issue is how this is actually implemented by the compiler?
move
simply returns an rvalue reference to its argument, equivalent to
static_cast<typename remove_reference<T>::type&&>(t)
The result of the function call is an rvalue (specifically, an xvalue), so it can be bound to an rvalue reference where the function argument couldn't. This allows you to explicitly move from an lvalue, using move
to convert it to an rvalue, while not allowing you to accidentally move from it.
forward
is similar, but overloaded to return an rvalue reference to an rvalue or rvalue reference, and an lvalue reference to anything else.
If an l-value is something you can get the address of
That's more or less correct. The official definition is that the expression "designates a function or an object", and those are things that have addresses.
and an r-value is exclusively not an l-value
Not really. Simplifying slightly, an expression is either a lvalue or an rvalue, but can be converted from one to the other. An lvalue can be implicitly converted to an rvalue; converting the other way can be done with a cast, as move
does.
how can you actually implement these references?
Just like any other reference - as an alias for, or a pointer to, the object it's bound to. The only difference is which kinds of expression can be used to denote (and possibly create) the object that's bound to the reference.
Do these new facilities allow for something like auto x = &(3);
That attempts to take the address of an rvalue directly, which isn't allowed. Since the question is about references, not pointers, the following are allowed, binding a reference to a temporary object (whose lifetime is extended to match the reference):
auto && rvalue = 3;
auto const & const_lvalue = 3;
while it's not allowed to bind it to a non-const lvalue reference
auto & lvalue = 3; // ERROR