What kind of problems for not forwarding universal reference?

c++, c++11, perfect-forwarding, universal-reference

Solution

There is no such rule to always use `std::forward` with universal references. On the contrary, it can be dangerous to use `std::forward` all over the place in functions with universal references. Take a look at the following example:

template <typename T>
auto make_pair(T&& t)
{
    return std::make_tuple(std::forward<T>(t), std::forward<T>(t)); // BAD
}

If you call this function with `make_pair(std::string{"foobar"})`, the result is counter-intuitive, because you move from the same object twice.

Update: Here is another example to show, that it really makes sense to use universal references without perfect forwarding:

template <typename Range, typename Action>
void foreach(Range&& range, Action&& action)
{
    using std::begin;
    using std::end;
    for (auto p = begin(range), q = end(range); p != q; ++p) {
        action(*p);
    }
}

- It's good that range is a universal reference, so that the caller can use foreach with a temporary container and an action, that's calls a non-const member function on the elements.

- It's good that action is a universal reference, so that the caller can pass a mutable lambda expression as action.

- And it would be wrong to use `std::forward` for range or for action.

Problem

As far as I know, in C++11, universal reference should always be used with `std::forward`, but I am not sure of what kind of problem can occur if `std::forward` is not used. ``` template <T> void f(T&& x); { // What if x is used without std::forward<T>(x) ? } ``` Could you provide some illustrations of problems that could occur in this situation ?

Original source

Related problems