适当的方式来转发右值参考

roz*_*ina 10 c++ move forward c++11

我有以下代码:

#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");
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,void bar(const std::string& str)调用了重载.如果我想要bar(std::string&& str)调用void 重载,我要么必须写bar(std::move(str));bar(std::forward<std::string>(str));

显然,前向代码更长,但对我来说更有意义.我的问题是什么是更常用和更喜欢的.写作bar(std::forward(str));将是最好的解决方案imo,但这不是一个选项:)

Mar*_* A. 8

引用Effective Modern C++

从纯粹的技术角度来看,答案是肯定的:std :: forward可以做到这一切.std :: move不是必需的.当然,这两种功能都不是必需的,因为我们可以在任何地方写出演员,但我希望我们同意那将是,令人讨厌的.std :: move的吸引力很方便,错误的可能性降低,清晰度更高.

std::move在这里使用

void foo(std::string&& str)
{
    bar(str);
}
Run Code Online (Sandbox Code Playgroud)

将返回str作为右值引用(这正是您试图实现的),而在使用时std::forward将返回左值引用(您不感兴趣)或右值引用(因此在这种情况下等效std::move).显然使用none只会继续调用那个,const std::string& str因为str在该函数中是左值.

底线:他们会做同样的事情,但是std::move因为使用是优选的

  • 它避免显式指定模板参数
  • 这更具惯用性
  • 它直截了当:std::forward不打算以那种方式使用(cfr.通用引用)或在那种情况下使用它虽然它肯定会起作用

我可能同意" 我将这个右值引用转发给另一个函数 "作为一个独立的句子可能有意义,但它有点遗漏了问题的关键点.你可以重新连接你的大脑,让它像" 保持'移动'这个左值引用到另一个函数 "

也可能相关:https://stackoverflow.com/a/18214825/1938163


Mel*_*kon 5

只要您确定它是右值参考,您就可以移动它.

当您无法确定是否为右值或左值参考时,应在模板化代码中使用Forward.:)

模板化代码&&表示通用引用,可以是rvalue或lvalue.

还要注意,std :: move在没有任何检查的情况下进行投射,与前进不同,因此如果您不确定要做什么,前进更安全,那么移动速度更快.