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

Why use std::forward rather than std::move for data member in rvalue reference constructor's initialization list?

我已经阅读了这些材料:

What's the difference between std::move and std::forward

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

前进

class ClassRoom
{
private:
    vector<string> students;

public:
    ClassRoom(vector<string>&& theStudents)
        :students{std::forward<vector<string>>(theStudents)}
    {
    }
}

移动

class ClassRoom
{
private:
    vector<string> students;

public:
    ClassRoom(vector<string>&& theStudents)
        :students{std::move(theStudents)}
    {
    }
}

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

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

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

template<typename Arg>
ClassRoom(Arg&& theStudents)
    :students{std::forward<Arg>(theStudents)}
{
}  

v.s.

template<typename Arg>
ClassRoom(Arg&& theStudents)
    :students{std::move(theStudents)}
{
}

然后:

vector<string> local_students = /* ... */;
ClassRoom cr(local_students) 

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

转发:

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

移动:

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

我会在这里使用 std::movestd::forward 旨在转发通用引用。在这种情况下没有通用参考。 虽然在这个例子中没有什么区别,但 std::move 更简洁,更自我记录。