参数转发

模板可以使用转发引用接受左值和右值引用

template <typename T>
void f(T &&t);

在这种情况下,将根据上下文推导真实类型的 t

struct X { };

X x;
f(x); // calls f<X&>(x)
f(X()); // calls f<X>(x)

在第一种情况下,类型 T 被推断为 XX&)的参考,t 的类型是对 X左值参考,而在第二种情况下,T 的类型推导为 Xt 的类型推导为 rvalue 参考到 XX&&)。

注意: 值得注意的是,在第一种情况下,decltype(t)T 相同,但不在第二种情况下。

为了将 t 完美地转发到另一个函数,无论是左值还是左值引用,都必须使用 std::forward

template <typename T>
void f(T &&t) {
    g(std::forward<T>(t));
}

转发引用可以与可变参数模板一起使用:

template <typename... Args>
void f(Args&&... args) {
    g(std::forward<Args>(args)...);
}

注意: 转发引用只能用于模板参数,例如,在以下代码中,v 是一个右值引用,而不是转发引用:

#include <vector>

template <typename T>
void f(std::vector<T> &&v);