33

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();
}
Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
GuLearn
  • 1,814
  • 2
  • 18
  • 32
  • Keep in mind that removing an element from a vector invalidates the iterator. If you are doing this in a loop you need to handle it slightly different than just erasing the element. – Captain Obvlious Apr 16 '14 at 19:26
  • 2
    @ChrisJester-Young I think they mean `std::move`. In which case the iterators remain valid. – juanchopanza Apr 16 '14 at 19:27
  • 1
    state is unspecified, not undefined. See the duplicate… – galop1n Apr 16 '14 at 19:31
  • 4
    @galop1n No it's not. I'm not talking about the state of an object after moving it. But the state of a container after moving its element – GuLearn Apr 16 '14 at 19:32
  • @YZ It is exactly the same by extension. – galop1n Apr 16 '14 at 19:33
  • 1
    @YZ.learner: Why do you think screwing around with an object change the state of the container in any way? – Mooing Duck Apr 16 '14 at 19:33
  • 1
    @galop1n I don't even call `std::move(v2)`! What I did is `std::move(v2[0])`. Also, I do `v2.clear()` before reuse it. By what extension do you think they are the same? – GuLearn Apr 16 '14 at 19:34
  • @MooingDuck Because if the behavior is `undefined`, then it could screw up anything. Isn't it? – GuLearn Apr 16 '14 at 19:35
  • @YZ.learner: are you sure you want std::move?? I guess from your question you just want to keep reusing the same vector and are just concerned that if you remove an element something will go wrong... am I correct? – Chris Maes Apr 16 '14 at 19:36
  • 1
    @ChrisMaes No, you are not. How could you even come up with that thought? – GuLearn Apr 16 '14 at 19:37
  • could you then provide a code example of what you want to obtain? this is quite unclear... – Chris Maes Apr 16 '14 at 19:38
  • If it is for optimization, I guess you could std::swap instead and all objects will still be healthy. – StellarVortex Apr 16 '14 at 19:38
  • 1
    @YZ.learner: changing the state of an element to any other valid state doesn't affect any container in any way. – Mooing Duck Apr 16 '14 at 19:50
  • 4
    @galop1n: "It is exactly the same by extension." -- No, it is absolutely not the same. – Benjamin Lindley Apr 16 '14 at 19:54
  • @MooingDuck You said *screwing around with an object*, and now you are talking about *valid state* !?!?! – GuLearn Apr 16 '14 at 19:55
  • @galop1n Would you mind to remove your incorrect dup flag? – GuLearn Apr 16 '14 at 20:18
  • @StellarVortex But how could I efficiently swap something *into* the vector? That's break the memory of the vector, doesn't it? – GuLearn Apr 16 '14 at 20:25
  • 1
    @YZ.learner: WRT: valid state: yes. No matter how you screw around with an object, if you leave it in valid state, that doesn't affect any container in any way. WRT swapping: You swap something in, and something (empty state?) out. He's not referring to appending or actual insertion. – Mooing Duck Apr 16 '14 at 20:39
  • But, if you are moving the entire vector, then the capacity of the original vector would not be the same. – Jagannath Apr 16 '14 at 21:16
  • 1
    This question should absolutely be reopened, it has nothing to do with the linked "duplicate". I just voted to reopen. – Boris Dalstein Oct 19 '18 at 13:46
  • @BorisDalstein Me, too. He's asking about taking elements out of `std::vector`. He's not asking whether the original element (moved FROM) will be valid or usable or known state, but how the `std::vector` will handle having its elements moved out. – lmat - Reinstate Monica Feb 04 '22 at 16:45
  • @BenjaminLindley There's only one vote required to reopen this question: maybe you'd like to also vote to reopen? Reminder: you already agreed in comments that it's not a duplicate, and you have the top-voted and accepted answer. – Boris Dalstein Feb 04 '22 at 18:06

1 Answers1

41

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.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274