5

I have read these materials:

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

std::move Vs 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.

Forward

class ClassRoom
{
private:
    vector<string> students;

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

Move

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?

Chen Li
  • 4,824
  • 3
  • 28
  • 55
  • 2
    The answer is: don't. Use `std::forward` when you want to perfect forward a deduced parameter (template/auto) - this **may** become equivalent to `std::move` (when the deduced parameter is an rvalue reference). Use `std::move` when you want to move from. – geza Nov 03 '17 at 12:16

2 Answers2

6

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

Caleth
  • 52,200
  • 2
  • 44
  • 75
1

I would use std::move here. std::forward is intended to forward universal references. There is no universal references in this case. Although in this example it'll be no difference, std::move is more concise and more self documenting.

Elohim Meth
  • 1,777
  • 9
  • 13