baran rvalue or an lvalue?
The question answers itself. Whatever has a name is an lvalue(1). So
bar is an lvalue. Its type is “rvalue reference to
string“, but it’s an lvalue of that type.
If you want to treat it as an rvalue, you need to apply
std::move() to it.
If you can perform any operation on an rvalue reference that you can on an lvalue reference what is the point in differentiating between the two with the “&&” instead of just an “&”?
This depends on your definition of “perform an operation.” An lvalue reference and a (named) rvalue reference are pretty much identical in how you can use them in expressions, but they differ a lot in what can bind to them. Lvalues can bind to lvalue references, rvalues can bind to rvalue references (and anything can bind to an lvalue reference to
const). That is, you cannot bind an rvalue to an lvalue reference, or vice versa.
Let’s talk about a function parameter of rvalue reference type (such as your
bar). The important point is not what
bar is, but what you know about the value to which
bar refers. Since
bar is an rvalue reference, you know for certain that whatever bound to it was an rvalue. Which means it’s bound to be destroyed when the full expression ends, and you can safely treat it as an rvalue (by stealing its resources etc.).
If you’re not the one doing this directly to
bar, but just want to pass
bar on, you have two options: either you’re done with
bar, and then you should tell the next one who receives it that it’s bound to an rvalue—do
std::move(bar). Or you’ll need to do some more things with
bar, and so you do not want anyone inbetween stealing its resources from under you, so just treat it as an lvalue—
To summarise it: The difference is not in what you can do with the reference once you have it. The difference is what can bind to the reference.
(1) A good rule of thumb, with minor exceptions: enumerators have names, but are rvalues. Classes, namespaces and class templates have names, but aren’t values.