2011-08-11 14:19:12 8 Comments
Does the standard define precisely what I can do with an object once it has been moved from? I used to think that all you can do with a moved-from object is do destruct it, but that would not be sufficient.
For example, take the function template swap
as defined in the standard library:
template <typename T>
void swap(T& a, T& b)
{
T c = std::move(a); // line 1
a = std::move(b); // line 2: assignment to moved-from object!
b = std::move(c); // line 3: assignment to moved-from object!
}
Obviously, it must be possible to assign to moved-from objects, otherwise lines 2 and 3 would fail. So what else can I do with moved-from objects? Where exactly can I find these details in the standard?
(By the way, why is it T c = std::move(a);
instead of T c(std::move(a));
in line 1?)
Related Questions
Sponsored Content
12 Answered Questions
[SOLVED] What are rvalues, lvalues, xvalues, glvalues, and prvalues?
- 2010-08-30 15:02:41
- James McNellis
- 167002 View
- 1295 Score
- 12 Answer
- Tags: c++ expression c++-faq c++11
23 Answered Questions
[SOLVED] What is the "-->" operator in C++?
- 2009-10-29 06:57:45
- GManNickG
- 753224 View
- 8609 Score
- 23 Answer
- Tags: c++ operators code-formatting standards-compliance
9 Answered Questions
37 Answered Questions
21 Answered Questions
13 Answered Questions
[SOLVED] What is a smart pointer and when should I use one?
- 2008-09-20 00:09:24
- Alex Reynolds
- 543292 View
- 1736 Score
- 13 Answer
- Tags: c++ pointers c++11 smart-pointers c++-faq
7 Answered Questions
[SOLVED] C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?
- 2011-06-11 23:30:14
- Nawaz
- 209442 View
- 1820 Score
- 7 Answer
- Tags: c++ multithreading c++11 language-lawyer memory-model
11 Answered Questions
[SOLVED] What is move semantics?
- 2010-06-23 22:46:46
- dicroce
- 389666 View
- 1621 Score
- 11 Answer
- Tags: c++ c++-faq c++11 move-semantics
24 Answered Questions
[SOLVED] Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition
- 2012-04-16 04:23:16
- Charles Menguy
- 179856 View
- 1591 Score
- 24 Answer
- Tags: c++ algorithm image-processing opencv
11 Answered Questions
[SOLVED] What does the explicit keyword mean?
- 2008-09-23 13:58:45
- Skizz
- 812731 View
- 2763 Score
- 11 Answer
- Tags: c++ constructor explicit c++-faq explicit-constructor
2 comments
@Howard Hinnant 2011-08-11 15:09:57
17.6.5.15 [lib.types.movedfrom]
When an object is in an unspecified state, you can perform any operation on the object which has no preconditions. If there is an operation with preconditions you wish to perform, you can not directly perform that operation because you do not know if the unspecified-state of the object satisfies the preconditions.
Examples of operations that generally do not have preconditions:
get
,empty
,size
Examples of operations that generally do have preconditions:
This answer now appears in video format here: http://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s
@fredoverflow 2011-08-11 15:17:16
But I could simply check the preconditions just like with any other object, right?
@Chris says Reinstate Monica 2011-08-11 15:18:33
@FredOverflow As long as these checks themselves have no preconditions, of course.
@Howard Hinnant 2011-08-11 15:20:18
@Christian: Exactly!
@fredoverflow 2011-08-11 15:25:58
@Chris: But how is that different from a normal, not moved-from object?
@Chris says Reinstate Monica 2011-08-11 15:27:45
@FredOverflow Who said a moved-from object is different from a non-moved object. That is the point in all the answers (well, except 6502's), a moved-from object is still a completely valid and usable object. You just don't know in which (valid) state it is. Like said, moving doesn't destroy the object, but alter it.
@Howard Hinnant 2011-08-11 15:30:02
@FredOverflow: The only difference is that most operations leave an object in a specified state. The moved-from state is unspecified, but otherwise, not special. Of course if you are the author of your class, you are free to make your moved-from state as special as you want. But know that if you use your class in std algorithms, your type is required to meet the stated requirements of the std algorithm, whether in a moved-from state or not ([utility.arg.requirements], Tables 20 and 22).
@UncleBens 2011-08-11 15:32:10
May-be should be a separate question, but does that mean: if I have a string with
char* buffer;
andint length;
members, then my move constructor/assignment must swap (or set) the value of both? Or would it be OK, if the length was unspecified (meaning thatempty
andsize
return meaningless values)?@6502 2011-08-11 15:33:42
Amazing how the standard uses "shall be placed in a valid but unspecified state" when the code that will do this operation is possibly generated by the compiler. All of a sudden we got classes that were perfectly valid and idiomatic in C++ and that in C++0X are violating the standard because C++0X will automatically generate a broken move constructor.
@Chris says Reinstate Monica 2011-08-11 15:34:32
@UncleBens In this case your string object would be in an invalid state, I think, which should answer your question. Not all unspecified states are valid, but only the valid ones should be taken by moved-from objects.
@fredoverflow 2011-08-11 15:52:12
@Uncle: I think that warrants its own question. You have my upvote for sure ;)
@Puppy 2011-08-11 16:33:23
@6502: Will you please stop just ranting on and on? This is not the place.
@6502 2011-08-11 19:21:18
@UncleBens: In you class probably if there is a move constructor or move assignment it would be written by you. The compiler will not generate a move operation for a class that has an explicit destructor.
@MSalters 2011-08-12 09:27:59
@6502: You don't make sense. A C++03 class isn't "violating the C++0x standard" because a move ctor if generated would violate the standard. And C++03 code wouldn't be moving that class so there's no reason for a move ctor to be generated.
@6502 2011-08-12 11:40:35
@MSalters: C++03 code can well put an object in an
std::vector
and callstd::sort
on that vector. The resulting code will possibly use move semantic including assignment to a moved-from object when compiled in C++0X mode. This by the way is not the only incompatible change... even juststd::vector<X> v(n);
has a different semantic in C++0X.@sdenham 2017-03-26 14:38:14
@UncleBens If empty or size (or any member function) might return meaningless values, the class would be effectively unusable. Also, if the buffer's storage was dynamically allocated by the class, you have to ensure that it is freed at some point, and that also applies to the buffer held by the target prior to the move. Furthermore, the source object's destructor must not apply free to an invalid address, or to the address it moved to the target. Swapping satisfies these rules, as, presumably, does freeing the destination's original buffer and setting the source to {0,nullptr}.
@Puppy 2011-08-11 14:30:45
Moved-from objects exist in an unspecified, but valid, state. That suggests that whilst the object might not be capable of doing much anymore, all of its member functions should still exhibit defined behaviour — including
operator=
— and all its members in a defined state- and it still requires destruction. The Standard gives no specific definitions because it would be unique to each UDT, but you might be able to find specifications for Standard types. Some like containers are relatively obvious — they just move their contents around and an empty container is a well-defined valid state. Primitives don't modify the moved-from object.Side note: I believe it's
T c = std::move(a)
so that if the move constructor (or copy constructor if no move is provided) is explicit the function will fail.@Howard Hinnant 2011-08-11 14:40:51
Not all of its member functions will exhibit defined behavior. Only those with no preconditions. For example you probably don't want to
pop_back
a moved-fromvector
. But you can certainly find out if it isempty()
.@Puppy 2011-08-11 14:50:25
@Howard Hinnant:
pop_back
from an emptyvector
has undefined behaviour anyway, from memory, so I'm pretty sure thatpop_back
from a moved vector exhibiting undefined behaviour is consistent.@Howard Hinnant 2011-08-11 15:11:29
We're discussing moved-from objects. Not objects known to be in an empty state. Moved-from objects have an unspecified state (unless of course otherwise specified). [lib.types.movedfrom]
@Chris says Reinstate Monica 2011-08-11 15:15:42
@Howard Unspecified, but valid, so
pop_back
still behaves like on any valid vector (may it even be an empty vector).@Red XIII 2013-02-01 16:15:56
I understand it as follows: the state of the object after moving can be in any valid state, and all the actions valid for the state can still be used. If the committee wanted they would have to go great lengths of specifying every possible state of object.
@Ankur S 2018-06-19 12:41:28
what do unspecified and valid mean in this context?
@Simon 2019-09-12 14:17:55
Defined behavior does not mean a defined result. So taking the example of a moved-from
vector
, one can find out if it isempty()
, but one cannot expect that this returns a specified result, be it true or false.