Reputation: 1864
I have a std::vector<std::string>
to be re-used in a loop. Is it ok to std::move
elements out? If I moved the ith element out, then ith slot goes into an undefined but valid state, but what about the vector? Is its state still defined and valid? Also, can I clear()
and then reuse the vector in the next iteration?
EDIT: please read the question before you flag for duplication. I'm asking the state of v2
after doing std::move(v2[0])
, not std::move(v2)
. Also I reuse v2
after I did v2.clear()
. How is that similar to the suggested duplication?
EDIT: code example:
struct Foo {
string data;
/* other data memebers */
void workOnData();
}
std::vector<std::string> buffer;
Foo foo;
while (1) {
buffer.clear();
loadData(buffer); // push data to buffer, at least one element in buffer guaranteed
foo.data.assign(std::move(buffer[0])); // please don't ask is Foo necessary or why workOnData has to be a member method. THIS IS A SIMPLIFIED EXAMPLE!
foo.workOnData();
}
Upvotes: 35
Views: 12790
Reputation: 67306
You can move
an object out of a vector, but it isn't likely done how you'd expect
You have to use a std::move_iterator
to do it. Constructing a std::move_iterator
is possible on any container using std::make_move_iterator
as follows:
auto print = [](const vector<string> &vec) {
for( auto&& s : vec )
puts( s.c_str() );
};
vector<string> v = { "A string", "Another one" };
puts( "Your strings:" );
print( v );
// MOVE begin element. Good place for auto? Maybe not even!
std::move_iterator< std::vector<string>::iterator > it = std::make_move_iterator( v.begin() );
puts( "Making the iterator doesn't move anything yet" );
print( v );
string moved = *it;
puts( "Dereferencing the move iterator moves the element it points to" );
print( v );
// Note: if you receive the result of the move_iterator
// into a string&&, it won't actually move it (seems to only alias it)
Upvotes: 0
Reputation: 103741
Is it ok to std::move elements out?
Yes, it's okay.
If I moved the ith element out, then ith slot goes into an undefined but valid state
It leaves the element in a valid but unspecified state. The difference between those two words is important in C++, but probably not too important to this question. Just thought I should point it out.
but what about the vector?
The vector is in a valid and well-specified state, though one of its elements is in an unspecified state.
Also, can I clear() and then reuse the vector in the next iteration?
Yes. Of course. Though you can do a lot more than that. Unlike a moved-from vector, you can still count on the vector having the same size, the same capacity, and all elements other than the one you just moved from remaining unchanged. As well as all references and iterators to elements (including the one you just moved from) remaining valid.
Upvotes: 41