Question

This question already has an answer here:

After moving an object, it must be destructable:

T obj;
func(std::move(obj));
// don't use obj and let it be destroyed as normal

But what else can be done with obj? Could you move another object into it?

T obj;
func(std::move(obj));
obj = std::move(other);

Does this depend on the exact type? (E.g. std::vector could make specific guarantees you can't rely on for all T.) Is it required or even sane that all types support something besides destruction on moved-from objects?

Was it helpful?

Solution

Yes, you can move another object into it. std::swap does this.

OTHER TIPS

The current draft of C++0x requires that a moved-from object can be destroyed or assigned to. If you pass your object to a function in the standard library then that is all that is assumed.

It is generally considered good practice to ensure that a moved-from object is a "working" object of its type that satisfies all invariants. However, it is in an unspecified state --- if it is a container, you don't know how many elements it has, or what they are, but you should be able to call size() and empty(), and query it.

The current draft is unclear on what is required of the standard library types themselves, and there is active discussion in the C++ committee about that.

That's type semantics. You decide. It's up to you how you implement the move.

In general, the state should be the same as the one gained by using non-parametric constructor.

Btw. move makes only sense if you are storing a data block behind a pointer (or some other movable class).

It depends on the class code. If class doesn't have rvalue reference constructor and assignment operator, std::move is ignored. std::move doesn't move anything, it just allows to treat its argument as rvalue reference, if appropriate function is available.

Correctly written && constructor and operator= must leave parameter instance in some consistent state, like empty string, and object should be usable. If there is operator=, another object may be correctly assigned to such empty instance.

Edit.

Generally, std::move should be used to apply move semantics to variable which is not rvalue, but actually it is:

SomeClass::SomeClass(SomeClass&& v)
{
    // Inside of this function, v is not rvalue anymore. But I know that actually 
    // this is rvalue, and use std::move
    OtherFunction(std::move(v));
}

In this case, mininal requirement to v is that it should be able to die without problems.

When std::move is used for variable which is not actually rvalue reference, really, this variable usability may be undefined. For my own classes, I would ensure some kind of consistency for this case. For another classes - it depends on specific class implementation, but I would not apply std::move to objects which are not actually rvalue references. I really don't know how this is defined (and whether it is defined) in the standard.

As I finally understood from the comments. You should check this: http://www.boost.org/doc/libs/1_44_0/libs/concept_check/concept_check.htm

This will allow you to check the type supplied as template parameters for concepts (features of the type). I'm not sure if they already have one for movable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top