问题
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?
回答1:
Yes, you can move another object into it. std::swap does this.
回答2:
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.
回答3:
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).
回答4:
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.
回答5:
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.
来源:https://stackoverflow.com/questions/3872521/how-can-moved-objects-be-used