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;
}