std::forward
是 C++11 中引入的一个函数模板,它用于在泛型编程中将参数以“原始”的方式转发给其他函数。
在 C++ 中,当我们将一个参数传递给函数时,其实是将这个参数的值拷贝一份传递给函数。如果该参数是一个左值引用类型,则会将其转换为右值引用,但仍然只是拷贝了一份数据。
当我们在实现一个泛型函数或类时,需要将接受到的参数再次传递给其他函数。如果我们直接将参数传递给该函数,那么参数的值会被拷贝两次,这样会导致性能上的损失。而且有些情况下,我们希望将参数作为左值或右值进行转发,此时是通过 std::move 和 std::forward 来实现的。
std::forward
通过完美转发(perfect forwarding)来实现这一点。完美转发意味着在转发过程中保持原始参数的值类别(value category),即左值还是右值。因此,当我们需要将一个参数作为左值或右值进行转发时,可以使用 std::forward
函数来实现。
std::forward与引用的区别
std::forward
与 &
虽然都涉及到参数的引用类型,但它们的作用是不同的。
&
是引用运算符,用于声明一个变量或参数为左值引用类型,表示该变量或参数可以绑定到一个左值(lvalue)上。左值引用类型的变量或参数可以修改其所绑定对象的值。
而 std::forward
是一个函数模板,用于在泛型编程中实现完美转发(perfect forwarding)。它根据参数的类型和值类别来决定将参数转发为左值引用或右值引用。通常用于将参数以原始的方式转发给其他函数。
例子:
#include <iostream>
#include <utility>
void foo(int& x) {
std::cout << "x is an lvalue reference\n";
}
void foo(int&& x) {
std::cout << "x is an rvalue reference\n";
}
template<typename T>
void bar(T&& x) { // x is a universal reference
foo(std::forward<T>(x)); // forward x as either an lvalue or rvalue
}
int main() {
int a = 42;
bar(a); // call foo(int&)
bar(100); // call foo(int&&)
return 0;
}
在这个例子中,我们定义了两个重载的函数 foo
,分别接受一个左值引用类型和一个右值引用类型的参数。我们还定义了一个函数模板 bar
,它使用了一个通用引用(universal reference) T&&
,来接受任意类型的参数,并将该参数转发给 foo
。
在 bar
中,我们使用 std::forward
来将参数 x
以原始的方式转发给函数 foo
。当我们调用 bar(a)
时,由于 a
是一个左值,因此 T
会被推导为 int&
,这样 x
也就成为了一个左值引用类型,最终调用了 foo(int&)
。而当我们调用 bar(100)
时,由于 100
是一个右值,因此 T
会被推导为 int&&
,这样 x
也就成为了一个右值引用类型,最终调用了 foo(int&&)
。