Search code examples
c++c++11overload-resolutionrvalue

C++11 lvalue, rvalue and std::move()


I have the following code:

#include <iostream>
using namespace std;
void test(int& a) {
    cout << "lvalue." << endl;
}
void test(int&& a) {
    cout << "rvalue" << endl;
}
int main(int argc, char *argv[]) {
    int a = 1;
    int&& b = 2;
    test(a);
    test(1);
    test(std::move(a));
    test(b);
}

which outputs:

lvalue.
rvalue
lvalue.
lvalue.

std::move() and int&& are rvalue references, I wonder why test(std::move(a)) and test(b) output lvalue? Is it related with signature matching and function overloading?


Solution

  • The output should be:

    lvalue.
    rvalue
    rvalue
    lvalue.
    

    There is a very important distinction to be made between expressions which are rvalues and expressions whose type is an rvalue reference. The type of b is an rvalue reference to int, but the expression b is an lvalue; it is a variable, you can take its address. This is why the final line of output is lvalue rather than rvalue. In order to change it to an rvalue, you should call std::move on it:

    test(std::move(b));