I've been trying to wrap my head around how move semantics in C++11 are supposed to work, and I'm having a good deal of trouble understanding what conditions a moved-from object needs to satisfy. Looking at the answer here doesn't really resolve my question, because can't see how to apply it to pimpl objects in a sensible way, despite arguments that move semantics are perfect for pimpls.
The easiest illustration of my problem involves the pimpl idiom, like so:
class Foo {
std::unique_ptr<FooImpl> impl_;
public:
// Inlining FooImpl's constructors for brevity's sake; otherwise it
// defeats the point.
Foo() : impl_(new FooImpl()) {}
Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {}
Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {}
Foo & operator=(Foo rhs)
{
std::swap(impl_, rhs.impl_);
return *this;
}
void do_stuff ()
{
impl_->do_stuff;
}
};
Now, what can I do once I've moved from a Foo
? I can destroy the moved-from object safely, and I can assign to it, both of which are absolutely crucial. However, if I try to do_stuff
with my Foo
, it will explode. Before I added move semantics for my definition of Foo
, every Foo
satisfied the invariant that it could do_stuff
, and that's no longer the case. There don't seem to be many great alternatives, either, since (for example) putting the moved-from Foo
would involve a new dynamic allocation, which partially defeats the purpose of move semantics. I could check whether impl_
in do_stuff
and initialize it to a default FooImpl
if it is, but that adds a (usually spurious) check, and if I have a lot of methods it would mean remembering to do the check in every one.
Should I just give up on the idea that being able to do_stuff
is a reasonable invariant?
std::move(first, last, out)
). You can then reuse the memory block inside the container (aka the "moved-from" elements). – Gaytonstd::swap
works? – Phyliciaphylisclear
,empty
,begin
,c_str
) it is absolutely no garbage. That is the whole point of the good answers and the phrase "undefined but valid state". – Phyliciaphylis