I am a reasonably competent C++ user (not a complete noob). I have a class that acts as a resource handle. It makes sense for the class to have a move constructor and for the copy construtor to be deleted:
struct Foo {
Foo (int i) : // For sake of example.
x(i)
{}
Foo (Foo && f) :
x(f.x)
{
f.x = 0; // 0 is special and means "moved from".
}
Foo (const Foo & f) = delete;
private:
int x;
};
I've been doing this in a cargo-cult fashion for ages now and it works fine. Now I'm trying to step up a gear with my C++11 usage.
I have another class that keeps a vector
of Foo
:
struct Bar { // (Constructor added below)
std::vector<Foo> foos;
};
I'd like to write a constructor for Bar
where the caller passes in a vector<Foo>
. I'd like the entire vector that the caller provides to be moved into Bar.foos
. I want to make that explicit to the caller by making the constructor parameter a vector<Foo>&&
rather than a plain vector<Foo>&
. That way, the caller must std::move
the vector in to the constructor.
int main (int argc, char ** argv)
{
Foo f1 (1);
Foo f2 (2);
std::vector<Foo> v;
v.push_back (std::move(f1));
v.push_back (std::move(f2));
Bar b (std::move(v)); // I want the user to HAVE TO std::move v.
return 0;
}
I naively tried writing Bar
constructor like this:
struct Bar {
Bar (vector<Foo> && vf) :
foos (vf) // pass the rvalue reference into foos' constructor, right?
{}
std::vector<Foo> foos;
};
My computer has g++ 4.9.2 and clang++ 3.5.0 and they both give me a small explosion of errors. They're both trying to construct Bar.foos
using the vector copy constructor, which then fails because I've deleted the copy constructor of Foo
.
How can I give 'vf', the rvalue reference of vector<Foo>
straight to the constructor of 'foos'?
A named argument is not an rvalue, so you have to convert
vf
to an rvalue reference by callingstd::move
:Also, it's not quite correct to say that the user must call
std::move
for an rvalue parameter; there's no need forstd::move
when the argument is the return value of a function, which is the classic notion of an rvalue.