为什么在右值引用构造函数的初始化列表中对数据成员使用 std::forward 而不是 std::move ?

陳 力*_*陳 力 4 c++ move rvalue rvalue-reference c++11

我已经阅读了这些材料:

std::move 和 std::forward 有什么区别

std::move 与 std::forward

这个答案非常接近我的问题,但一个是setImage,另一个是右值引用构造函数,所以恐怕存在一些微妙的东西。

向前

class ClassRoom
{
private:
    vector<string> students;

public:
    ClassRoom(vector<string>&& theStudents)
        :students{std::forward<vector<string>>(theStudents)}
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

移动

class ClassRoom
{
private:
    vector<string> students;

public:
    ClassRoom(vector<string>&& theStudents)
        :students{std::move(theStudents)}
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

有人告诉我这forward是正确的方法,因为 的用法之一forward是将右值引用变量传递给其他人并保证不再使用它。但我不知道为什么不在move这里使用,他说的对吗?

Cal*_*eth 5

在这个例子中,std::movestd::forward做同样的事情。

如果您将示例更改为推导类型,则情况有所不同,例如

template<typename Arg>
ClassRoom(Arg&& theStudents)
    :students{std::forward<Arg>(theStudents)}
{
}  
Run Code Online (Sandbox Code Playgroud)

对比

template<typename Arg>
ClassRoom(Arg&& theStudents)
    :students{std::move(theStudents)}
{
}
Run Code Online (Sandbox Code Playgroud)

然后:

vector<string> local_students = /* ... */;
ClassRoom cr(local_students) 
Run Code Online (Sandbox Code Playgroud)

Arg推导出来vector<string>&,这意味着不同的事情发生

向前:

forward<vector<string>&>传递左值引用,因此 selected 的重载vector::vector是复制构造函数,local_students不受影响

移动:

move<vector<string>&>将左值引用强制转换为右值引用,因此 selected 的重载vector::vector是移动构造函数,local_students现在处于移动自状态

  • 你真的需要一个可变参数模板吗? (2认同)
  • 在这个例子中它是多余的,因为它基于只有一个参数的原始参数,因此可能会让读者误以为 `std::forward` 只对可变参数模板有意义 (2认同)
  • @Gruffalo:这是一个有效的评论。当我学习这些东西时,我犯了这个错误。 (2认同)