I have read these materials:
What's the difference between std::move and std::forward
this answer is very close to my question, but one is setImage
, the other is rvalue reference constructor, so I'm afraid something subtle exists.
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)}
{
}
}
Someone told me forward
is the right method here because one of the usages of forward
is to pass rvalue reference variable to others and guarantee not use it again. but I can't figure out why not to use move
here and is what he said right?
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