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

时间:2017-11-03 11:58:15

标签: c++ c++11 move rvalue-reference rvalue

我已阅读这些材料:

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

std::move Vs std::forward

this answer非常接近我的问题,但一个是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的一个用法是将rvalue引用变量传递给其他人,并保证不再使用它。但我无法弄清楚为什么不在这里使用move并且他说的是对的?

2 个答案:

答案 0 :(得分:3)

In this example, both std::move and std::forward do the same thing.

This is different if you change the example to a deduced type, e.g.

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

v.s.

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

Then:

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

Arg deduces to vector<string>&, which means different things happen

Forward:

forward<vector<string>&> passes along the lvalue-reference, so the overload of vector::vector chosen is the copy constructor, local_students is unaffected

Move:

move<vector<string>&> casts the lvalue-reference to rvalue-reference, so the overload of vector::vector chosen is the move constructor, local_students is now in the moved-from state

答案 1 :(得分:1)

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