C++C++ Explainer
C++ · 3 · Memory & Smart Pointers15 / 36 · 42%

Perfect Forwarding & Universal References

Pass arguments through a wrapper without losing their value category.

Examples: T&&, std::forward, variadic factory

shortcuts: ← prev · → next · M mark
1

Universal Reference

In a deduced template context, T&& binds to both lvalues and rvalues.

Example
example
template <typename T>
void wrapper(T&& arg);   // universal reference

void f(Widget&& arg);    // plain rvalue reference — NOT universal
2

std::forward

Restores the original value category when passing along.

Example
example
template <typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));   // lvalue stays lvalue, rvalue stays rvalue
}
WATCH OUT
Inside the function, arg itself is an lvalue (it has a name). Without forward, you always copy.
3

Variadic Factory

This is exactly how make_unique is written.

Example
example
template <typename T, typename... Args>
std::unique_ptr<T> my_make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
4

emplace vs push

emplace_back forwards constructor arguments and builds in place.

Example
example
std::vector<std::string> v;
v.push_back(std::string(10, 'x'));  // build temporary, then move
v.emplace_back(10, 'x');            // constructed directly in the vector