正确转发右值引用的方法
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)
重载。如果我想调用无效的bar(std::string&& str)
过载,我要么写bar(std::move(str));
要么写bar(std::forward<std::string>(str));
显然,转发代码更长,但对我来说更有意义。我的问题是哪个更常用和更受欢迎。在我看来,写bar(std::forward(str));
是最好的解决方案,但这不是一个选择:)
引自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
不打算以这种方式使用(cfr)。通用引用)或在这种情况下,尽管它肯定会起作用
我可能同意"我转发这个右值引用到另一个函数"作为一个独立的句子可能是有意义的,但它有点错过了问题的重点。你可以重新连接你的大脑,把它想象成"继续‘移动’这个右值引用到另一个函数"
也可能相关:https://stackoverflow.com/a/18214825/1938163
当你确定它是右值引用时,你可以移动它。
Forward应该在模板代码中使用,当你不能确定它是右值引用还是左值引用时。:)
模板代码&&平均通用引用,可以是右值,也可以是左值。
还需要注意的是,std::move是在没有任何检查的情况下强制转换它,不像forward,所以如果你不确定你应该做什么,forward更安全,move更快。
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 在 cpp 文件中隐藏采用模板参数引用的方法
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么常量方法可以采用非常量引用?
- 没有取消引用/解包对象的标准方法?
- C++方法中的引用变量
- 引用文件的适当方法是什么?
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 对结构方法的未定义引用
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- 使用移动语义:右值引用作为方法参数
- Unity3D 导入 C++ DLL 用于按引用方法传递
- 通过引用方法传递对象
- 无法将从函数返回的向量传递给需要引用方法的函数
- 正在调用指针和引用方法
- 与const引用(方法链)相关联的临时对象的生命周期
- 方法内部的简单c++成员引用(方法解析后的链接器错误)
- 被引用方法的未定义引用
- 无法引用方法
- 我如何在外面引用 C++ 方法