Forwarding References

Due to the shortcomings of lvalue and rvalue references in C++, forwarding references (or some would call it universal references) becomes the alternative for resources’ referencing or copying.

It is rather easy to confuse the syntax of rvalue references and forwarding references. Just remember that forwarding references is always come with template, and it is immediately attached to the type itself. See the following examples:

void f(Widget&& w);     // rvalue reference

template<typename T>
void f(Widget<T>&& w);  // still a rvalue reference

template<typename T>
void f(T&& w);          // forwarding reference

Forwarding references could be used alongside with variadic template in order to accept multiple arguments with no hassle of value type conversion. This is showed as the following:

template<typename... T>
void f(T&&... w) {
  do_something(std::forward<T>(w)...);
}

Although forwarding references is a good alternative for generality, it does not actually preserve the value type of the arguments after they enter the local scope. In order to do this, we need 202203291851#.

Caution

Because of the generality of forwarding reference, there is always a possibility that some functions does not do what you think. Remember this rule: C++ compiler will always find the perfect match for a generated function with the given parameters, otherwise a function with forwarding reference will almost always be chosen as the alternative.

Do not forward something twice! Once we have forwarded an object, it is not yours to use anymore.

Links to this page
  • Perfect Forwarding

    In some situation, we might want to preserve the value type of the arguments during #forwarding instead of toss away it after entering the local scope.

#cpp #resource