关于右值引用与完美转发
- 今日的疑问: 在下面的代码中,forwardFunction(n); // 为什么这里调用的是process(int&),而不是process(int&&)?
- 解答:
- 想要使用右值的方法有很多,如下:
今日的疑问: 在下面的代码中,forwardFunction(n); // 为什么这里调用的是process(int&),而不是process(int&&)?
#include <iostream>
#include <utility>
void process(int &x)
{
std::cout << "process(int& x):";
std::cout << "process called with lvalue: " << x << std::endl;
}
void process(int &&x)
{
std::cout << "process(int&& x):";
std::cout << "process called with rvalue: " << x << std::endl;
}
template <typename T>
void forwardFunction(T &&arg)
{
process(std::forward<T>(arg)); // 转发参数时保持原始值类别
}
int main()
{
int x = 10;
int &m = x; // 定义一个左值引用变量
int &&n = 10; // 定义一个右值引用变量
forwardFunction(m); // 调用 process(int&),传递一个左值引用
forwardFunction(n); // 为什么这里调用的是process(int&),而不是process(int&&)?
return 0;
}
解答:
在上面的代码中,forwardFunction(n) 调用的是 process(int&),而不是 process(int&&),
是因为: n 是一个右值引用变量,但它本身是一个左值。
右值引用变量可以绑定到一个右值,但它本身不是一个右值,而是一个具有名字的对象,可以被多次访问。
因此,当你将 n 传递给 forwardFunction 时,它会被推导为 int& 类型,而不是 int&& 类型。如果您想让 n 被当作右值传递,您需要使用 std::move(n) 来转换它。
std::forward 的作用是保持参数的原始值类别,即如果输入的参数是左值,那么传递给下一个函数的参数的也是左值;如果输入的参数是右值,那么传递给下一个函数的参数的也是右值1。这样可以实现完美转发,即根据参数的不同类型调用不同的重载函数。