C++ – std::move Not Working on RValue Reference Function

c++c++11rvalue-referencestdvector

While trying to learn std::move and rvalue reference , i just came across the following:

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vecNumbers;
    vecNumbers.push_back(10);
    vecNumbers.push_back(20);

    foo(std::move(vecNumbers));

    std::cout<<"After Move \n";
    std::cout<<"size:"<<vecNumbers.size()<<"\n";

    return 0;
}

void foo(  std::vector<int> &&value)
{
    std::cout<<"size in Function:"<<value.size()<<"\n";
}

The Output

size in Function:2
After Move
size:2

I was expecting the size to be 0 after calling move on vector but here it only moved as reference. Could someone please explain what is happening here.

Best Answer

std::move only casts to Rvalue reference.

foo takes Rvalue ref to vector<int>. By move(vecNumbers) you get vector<int>&&. Inside foo you just access vecNumbers which is defined in main. You didn't do any action which changed the content of this vector.

If you really want to move (steal) content of vecNumbers you have to call either move constructor or move assignment operator. Inside foo you could do this in this way:

void foo(  std::vector<int>&& value)
{
    std::vector<int> v1{std::move(value)}; // invoke move ctor which steals content of value
    std::cout<<"size in Function:"<<value.size()<<"\n";
}

or you can change signature of foo to be:

void foo(std::vector<int> value) {

}

then when you call

foo(std::move(vecNumbers))

move constructor of vector<T> is called which moves vecNumbers to value inside foo.