Below is a code demonstrating the question:
class X {};
X x;
X&& rvalue_ref = std::move(x);
static_assert(std::is_same<decltype(rvalue_ref), X&&>::value, "Different types"); //To be sure that type is X&&
void func(X&) {
cout << "lvalue reference";
}
void func(X&&) {
cout << "rvalue reference";
}
int main() {
func(rvalue_ref);
}
The output:
lvalue reference
Could you please explain the reason for that? We have a variable of the type X&& and an overload for this type but this overload isn't called.
References don't really work like that. Your argument
rvalue_ref, despite its type, is an lvalue expression. You would have to dostd::moveagain to make it an rvalue.Types and value categories are two separate things, and it can be hard to remember that an expression naming an rvalue reference typed object is not automatically an rvalue expression.
Consider also:
This is also mentioned on cppreference.com's "Value categories" article: