Key knowledge about forwarding references in C++

The compiler deduces U as std::string& or as std::string depending on value category of the argument:

template <class U>
void f(U&& s)
{
    static_assert(std::is_same_v<U, const std::string&>);

    std::cout << std::forward<U>(s) << std::endl;
}

int main()
{
    const std::string& s = "abc";

    f(s);

    return 0;
}
template <class U>
void f(U&& s)
{
    static_assert(std::is_same_v<U, std::string>);

    std::cout << std::forward<U>(s) << std::endl;
}

int main()
{
    f(std::string("abc"));

    return 0;
}

What happens when we try to move a const string:

template <class U>
void f(U&& s)
{
    static_assert(std::is_same_v<U, const std::string>);

    std::cout << std::forward<U>(s) << std::endl;
}

int main()
{
    const std::string& s = "abc";

    f(std::move(s));

    return 0;
}

std::forward<U>(s) basically does the type cast:

static_cast<U&&>(s)

But actually there are two std::forward overloads:

and there is a post Why does std::forward have two overloads? explaining what are they for.

Leave a Reply

Your email address will not be published.