Search code examples
c++move-semanticsrvalue-reference

Passing vector with std::move function signature


Consider the code below

void foo(std::vector<int> v)
{
   //do something here
}
//calling the function
vector<int> v1 = {1,2,3};
foo(std::move(v1));

My question is, isn't the function foo supposed to have signature void foo(std::vector<int>&& v) for it to be able to take the r value reference of the vector?


Solution

  • My question is, isnt the function foo supposed to have signature void foo(std::vector<int>&& v) for it to be able to take the r value reference of the vector?

    If that's what you want, then yes, but that doesn't mean what you have is incorrect. When you pass something to a function it copy initializes the parameter from the source. That means if you do

    vector<int> v1 = {1,2,3};
    foo(v1);
    

    then foo gets a copy of v1. With

    vector<int> v1 = {1,2,3};
    foo(std::move(v1));
    

    We copy initialize v from std::move(v1) and since std::move(v1) is an rvalue reference, the move constructor is chosen for v and v1 gets moved into the function.

    So, by taking by value you give the option to the caller to give it a temporary, give it a rvalue reference, which will both move the object into the function, or just let a copy happen. If you had void foo(std::vector<int>&& v) Then you could only pass a temporary or std::move() an lvalue. There would be no way to allow the caller to have a copy made without them making one themselves and then moving that copy into the function.