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.
Магистерский курс C++ (МФТИ, 2022-2023). Лекция 11. Вывод типов.
https://www.youtube.com/watch?v=zrZdBzXBZtE&list=PL3BR09unfgcgf7R88ZQRQqWOdLy4pRW2h&index=11