问题描述
在下面的代码中,为什么在传递参数时应该使用 std :: forward
?
In the code below, why should I use std::forward
when passing around arguments?
class Test {
public:
Test() {
std::cout << "ctor" << std::endl;
}
Test(const Test&) {
std::cout << "copy ctor" << std::endl;
}
Test(const Test&&) {
std::cout << "move ctor" << std::endl;
}
};
template<typename Arg>
void pass(Arg&& arg) {
// use arg..
return;
}
template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
// use arg...
return pass(args...); // why should I use std::forward<Arg>(args)... ?
}
int main(int argc, char** argv)
{
pass(std::move<Test>(Test()));
return 0;
}
带有或不带有 std :: forward
的代码不会显示任何复制/移动.
The code with or without std::forward
doesn't show any copy/move around.
推荐答案
关于 std :: forward
的功能及其工作方式(例如和).
There are a number of good posts on what std::forward
does and how it works (such as here and here).
简而言之,它保留其参数的值类别.完美的转发可以确保将提供给函数的参数转发给具有与最初提供的.它通常与模板函数一起使用,其中引用崩溃可能已经发生(涉及通用/转发参考).
In a nutshell, it preserves the value category of its argument. Perfect forwarding is there to ensure that the argument provided to a function is forwarded to another function (or used within the function) with the same value category (basically r-value vs. l-value) as originally provided. It is typically used with template functions where reference collapsing may have taken place (involving universal/forwarding references).
请考虑以下代码示例.删除 std :: forward
将打印出需要左值
,并添加 std :: forward
打印出需要右值
. func
根据是右值还是左值而被重载.在没有 std :: forward
的情况下调用它会导致错误的重载.在这种情况下,需要使用 std :: forward
,因为使用右值调用 pass
.
Consider the code sample below. Removing the std::forward
would print out requires lvalue
and adding the std::forward
prints out requires rvalue
. The func
is overloaded based on whether it is an rvalue or an lvalue. Calling it without the std::forward
calls the incorrect overload. The std::forward
is required in this case as pass
is called with an rvalue.
#include <utility>
#include <iostream>
class Test {
public:
Test() {
std::cout << "ctor" << std::endl;
}
Test(const Test&) {
std::cout << "copy ctor" << std::endl;
}
Test(Test&&) {
std::cout << "move ctor" << std::endl;
}
};
void func(Test const&)
{
std::cout << "requires lvalue" << std::endl;
}
void func(Test&&)
{
std::cout << "requires rvalue" << std::endl;
}
template<typename Arg>
void pass(Arg&& arg) {
// use arg here
func(std::forward<Arg>(arg));
return;
}
template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
// use arg here
return pass(std::forward<Args>(args)...);
}
int main(int, char**)
{
pass(std::move<Test>(Test()));
return 0;
}
这篇关于为什么要使用std :: forward?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!