c++c++11moveforward

Appropriate way to forward rvalue reference


I have the following code:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

void bar(const std::string& str)
{
    cout << "const str - " << str << endl;
}

void bar(std::string&& str)
{
    cout << "str - " << str << endl;
}

void foo(std::string&& str)
{
    bar(str);
}


int main()
{
    foo("Hello World");
}

In the above code the void bar(const std::string& str) overload gets called. If I want the void bar(std::string&& str) overload to be called I either have to write bar(std::move(str)); or bar(std::forward<std::string>(str));

Obviously the forward code is longer, but it makes more sense to me. My question is what is more commonly used and preferred. Writing bar(std::forward(str)); would be the best solution imo, but that is not an option :)


Solution

  • Citing from Effective Modern C++

    From a purely technical perspective, the answer is yes: std::forward can do it all. std::move isn’t necessary. Of course, neither function is really necessary, because we could write casts everywhere, but I hope we agree that that would be,well, yucky. std::move’s attractions are convenience, reduced likelihood of error, and greater clarity.

    Using std::move here

    void foo(std::string&& str)
    {
        bar(str);
    }
    

    will return str as an rvalue reference (which is exactly what you're trying to achieve) while using std::forward would return either an lvalue reference (which you're not interested in) or an rvalue reference (thus equivalent in this case to std::move). Obviously using none would just keep calling the const std::string& str one since str is an lvalue in that function.

    Bottom-line: they would do the same thing but using std::move is preferred since

    I might agree that "I'm forwarding this rvalue reference to the other function" might make sense as a standalone sentence but it kind of misses the point of the matter. You could re-wire your brain to think it like "Keep 'moving' this rvalue reference to the other function"

    Also possibly related: https://stackoverflow.com/a/18214825/1938163