转发右值引用的适当方法

问题描述 投票:0回答:2

我有以下代码:

#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));
将是最好的解决方案,但这不是一个选择:)

c++ c++11 move forward
2个回答
12
投票

引自Effective Modern C++

从纯粹的技术角度来看,答案是肯定的:std::forward 可以做到这一切。 std::move 不是必需的。当然,这两个函数都不是真正必要的,因为我们可以在任何地方编写强制转换,但我希望我们同意这会是,嗯,令人讨厌的。 std::move 的吸引力在于方便、减少错误的可能性和更高的清晰度。

在这里使用

std::move

void foo(std::string&& str)
{
    bar(str);
}

将返回

str
作为右值引用(这正是您想要实现的目标),而使用
std::forward
将返回左值引用(您不感兴趣)或右值引用(因此相当于这种情况
std::move
)。显然,使用 none 只会继续调用
const std::string& str
,因为
str
是该函数中的左值。

底线:他们会做同样的事情,但首选使用

std::move
,因为

  • 它避免显式指定模板参数
  • 比较地道
  • 它直奔主题:
    std::forward
    不打算以这种方式使用(参见通用参考)或在这种情况下使用,尽管它肯定会起作用

我可能同意“我将这个右值引用转发给另一个函数”作为一个独立的句子可能是有意义的,但它有点错过了问题的要点。你可以重新连接你的大脑,让它像“保持‘移动’这个右值引用到另一个函数

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


7
投票

只要确定它是右值引用,就可以移动它。

当您无法确定它是右值还是左值引用时,应该在模板化代码中使用Forward。 :)

在模板化代码中 && 表示通用引用,可以是右值或左值。

另请注意,std::move 会在没有任何检查的情况下进行转换,这与向前不同,因此,如果您不确定应该做什么,则向前更安全,而移动速度更快。

© www.soinside.com 2019 - 2024. All rights reserved.