0

I've read many articles saying that if there are no templates for the function, std::forward<>() does not become a conditional cast anymore and just basically casts objects to RValue reference. Is that true?

  • i think you are confusing universal references with using `std::forward`. `std::forward` is always a cast, but a `T&&` parameter is different depending on `T` being a template parameter or not – 463035818_is_not_an_ai Jun 22 '21 at 19:06
  • What is a `conditional cast`? – SergeyA Jun 22 '21 at 19:11
  • If there's no template, you already know the value category and don't need help preserving it in a generic way, so `std::forward` won't help you. Of course you could still use it (it'll cast to whatever you tell it to), but for no benefit and the chance of using it incorrectly. – chris Jun 22 '21 at 19:11

1 Answers1

2

std::forward has a relatively simple implementation. It could look like this:

template <typename T>
T&& forward( std::remove_reference_t<T> & param )
{
   return static_cast<T &&>(param);
}

As you can see, it's just a static_cast, and not conditional. Given some type T, it casts the result to T&&.

If T is a value type like std::string or an r-value reference like std::string&&, the result will always be an r-value reference.

If T is an l-value reference like std::string&, you are effecively performing static_cast<std::string& &&>(param) and the rules of reference collapsing will cast it to a l-value std::string&.

The reason that std::forward may feel like a conditional cast is because it is intended to be used with forwarding references. Forwarding reference types are either value types or l-value references, depending on the calling context.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180