, am I guaranteed after the erase that all pointers still in v are
valid. I know that given the intuitive implementation of
std::remove_if, and given all of the implementations I've looked at,
they will be. I'd like to know if there is anything in the standard
which guarantees it; i.e. that std::remove_if is not allowed to copy
any of the valid entries without recopying the copy into its final
location.

(I am, of course, supposing that the condition doesn't copy. If the
condition has a signature like:

unique_ptr is not copy constructible, so if you used that predicate your code wouldn't compile.
–
interjayDec 7 '11 at 12:12

1

Why not? std::unique is not copyable but movable. It can be moved to the end of container.
–
ali_bahooDec 7 '11 at 12:12

3

@KennyTM: But the predicate given in the question takes a parameter by value, so needs a copy constructor.
–
interjayDec 7 '11 at 12:16

2

@VJovic: No, he didn't. He gave that predicate as an example of one that does copy. Then he made an incorrect statement about pointers being invalidated, which would be true with auto_ptr but not unique_ptr (the code simply wouldn't compile).
–
interjayDec 7 '11 at 12:24

2 Answers
2

Note: each element in the range [ret,last), where ret is the returned
value, has a valid but unspeciﬁed state, because the algorithms can
eliminate elements by swapping with or moving from elements that were
originally in that range.

This means that it depends on your predicate operator. Since your predicate doesn't create a copy, then the elements are not going to be copied.

§25.3.8/1 is a constraint on the targetted type, not on the implementation of remove. §25.3.8/6 is what I was looking for. Too bad it's a note, and not normative. But it does make the intent clear. I should have read the notes, and not just the normative text, before posting. +1 anyway, and I'll consider it the final response if no one finds anything more definite.
–
James KanzeDec 7 '11 at 12:28

I believe that note is incorrect. Good thing it isn't normative. ;-) The algorithm is not allowed to swap elements because the elements aren't required to be Swappable. The algorithm can only use move assignment.
–
Howard HinnantDec 7 '11 at 15:11

Just like erase() and resize(), remove_if() will move elements (possibly via swapping), so the container elements do not need to be copyable. There's nothing special about unique_ptr, it's just another move-only type.

As you point out, the predicate should of course take elements by const-reference. Again, just like for any movable type.

Where is this stated in the standard? And more importantly, where is it stated that remove_if doesn't move to some temporary, perhaps later to leave the value there because it determines that doesn't need to put it elsewhere? The containers and there member functions have been reworded to reflect move semantics, but I'm not aware of any changes in the language describing remove_if in this regard.
–
James KanzeDec 7 '11 at 12:12

@JamesKanze: Note that the state of the "removed" elements is unspecified. Your pointers will be released at the latest when you erase the tail sequence or when you reassign the elements in it, but possibly sooner (i.e. the standard doesn't say).
–
Kerrek SBDec 7 '11 at 12:54

1

@JamesKanze: It wouldn't do that. It would only ever move the elements. If you don't have a copy constructor and the move constructor isn't noexcept, then it wouldn't even compile, I think, or at least then you have to live the the risk of having exceptions. (This follows from 17.6.3.5: Allocator Requirements.)
–
Kerrek SBDec 7 '11 at 14:20