转发右值引用的适当方式
Appropriate way to forward rvalue reference
我有以下代码:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
void bar(const std::string& str)
{
cout << "const str - " << str << endl;
}
void bar(std::string&& str)
{
cout << "str - " << str << endl;
}
void foo(std::string&& str)
{
bar(str);
}
int main()
{
foo("Hello World");
}
在上面的代码中,调用了 void bar(const std::string& str)
重载。如果我想调用 void bar(std::string&& str)
重载,我要么必须写 bar(std::move(str));
要么 bar(std::forward<std::string>(str));
显然转发代码更长,但对我来说更有意义。我的问题是什么更常用和更喜欢。在我看来,写 bar(std::forward(str));
是最好的解决方案,但这不是一个选择:)
引自Effective Modern C++
From a purely technical perspective, the answer is yes: std::forward can do it all. std::move isn’t necessary. Of course, neither function is really necessary, because we could write casts everywhere, but I hope we agree that that would be,well, yucky. std::move’s attractions are convenience, reduced likelihood of error, and greater clarity.
这里使用std::move
void foo(std::string&& str)
{
bar(str);
}
将 return str
作为右值引用(这正是您要实现的目标),而使用 std::forward
将 return 作为左值引用(你不感兴趣的)或右值引用(因此在这种情况下等同于 std::move
)。显然使用 none 只会继续调用 const std::string& str
一个,因为 str
是该函数中的左值。
底线:他们会做同样的事情,但使用 std::move
是首选,因为
- 避免显式指定模板参数
- 更地道
- 直截了当:
std::forward
不打算以这种方式使用(参见 Universal references)或在那种情况下使用,尽管它肯定会起作用
我可能同意“我正在将此右值引用转发给另一个函数”作为一个独立的句子可能有意义,但它有点忽略了问题的重点。你可以重新连接你的大脑,让它像“保持'moving'这个右值引用到另一个函数”
也可能相关:
只要确定它是右值引用,就可以移动它。
当您不能确定它是右值引用还是左值引用时,应在模板代码中使用 Forward。 :)
在模板代码中&&表示通用引用,可以是右值也可以是左值。
另请注意,std::move 是在没有任何检查的情况下施放它,这与向前不同,因此如果您不确定应该做什么,向前会更安全,但移动会更快。
我有以下代码:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
void bar(const std::string& str)
{
cout << "const str - " << str << endl;
}
void bar(std::string&& str)
{
cout << "str - " << str << endl;
}
void foo(std::string&& str)
{
bar(str);
}
int main()
{
foo("Hello World");
}
在上面的代码中,调用了 void bar(const std::string& str)
重载。如果我想调用 void bar(std::string&& str)
重载,我要么必须写 bar(std::move(str));
要么 bar(std::forward<std::string>(str));
显然转发代码更长,但对我来说更有意义。我的问题是什么更常用和更喜欢。在我看来,写 bar(std::forward(str));
是最好的解决方案,但这不是一个选择:)
引自Effective Modern C++
From a purely technical perspective, the answer is yes: std::forward can do it all. std::move isn’t necessary. Of course, neither function is really necessary, because we could write casts everywhere, but I hope we agree that that would be,well, yucky. std::move’s attractions are convenience, reduced likelihood of error, and greater clarity.
这里使用std::move
void foo(std::string&& str)
{
bar(str);
}
将 return str
作为右值引用(这正是您要实现的目标),而使用 std::forward
将 return 作为左值引用(你不感兴趣的)或右值引用(因此在这种情况下等同于 std::move
)。显然使用 none 只会继续调用 const std::string& str
一个,因为 str
是该函数中的左值。
底线:他们会做同样的事情,但使用 std::move
是首选,因为
- 避免显式指定模板参数
- 更地道
- 直截了当:
std::forward
不打算以这种方式使用(参见 Universal references)或在那种情况下使用,尽管它肯定会起作用
我可能同意“我正在将此右值引用转发给另一个函数”作为一个独立的句子可能有意义,但它有点忽略了问题的重点。你可以重新连接你的大脑,让它像“保持'moving'这个右值引用到另一个函数”
也可能相关:
只要确定它是右值引用,就可以移动它。
当您不能确定它是右值引用还是左值引用时,应在模板代码中使用 Forward。 :)
在模板代码中&&表示通用引用,可以是右值也可以是左值。
另请注意,std::move 是在没有任何检查的情况下施放它,这与向前不同,因此如果您不确定应该做什么,向前会更安全,但移动会更快。