Talk:cpp/algorithm/remove
From cppreference.com
Where in the standard is a requirement stating that the predicate for remove_if should not modify the objects passed to it? Benjamin Lindley 22:50, 27 April 2012 (PDT)
- It looks like there are some footnotes in 25.1 that describe general constraints on algorithms -- perhaps these are the source of that claim?
- "4. For purposes of determining the existence of data races, algorithms shall not modify objects referenced through an iterator argument unless the specification requires such modification."
- "8. ... The function object pred shall not apply any non-constant function through the dereferenced iterator."
- --Nate 05:11, 28 April 2012 (PDT)
- Yes, §25.1[algorithms.general]/8 (/7 in C++03) is almost certainly what the predicate template refers to. --Cubbi 07:36, 28 April 2012 (PDT)
- I see. That upsets me. I wonder why they considered such a requirement necessary. --Benjamin Lindley 09:19, 30 April 2012 (PDT)
- Maybe the standards committee is secretly trying to make C++ a functional programming langauge. But seriously, it doesn't seem to unreasonable to require that something called a 'predicate' not have side effects. --Nate 15:40, 30 April 2012 (PDT)
[edit] Mentioning file deletion overload?
Should this page mention that std::remove also has a unrelated (const char *) overload that deletes disk files? -- Myria (talk) 16:08, 2 June 2016 (PDT)
[edit] No invalidation of interators
We should mention that std::remove and std::remove_if do not invalidate iterators.
The erase-remove idiom relies on this:
Run this code
#include <vector> #include <algorithm> #include <cassert> int main() { { std::vector<int> vec{1, 2, 1, 3, 1, 4, 1, 5, 1}; auto e = vec.end(); auto rem = std::remove(vec.begin(), vec.end(), 1); assert(e == vec.end()); vec.erase(rem, vec.end()); //assert(e != vec.end()); // this will usually be hold } { std::vector<int> vec{1, 2, 1, 3, 1, 4, 1, 5, 1}; vec.erase(std::remove(vec.begin(), vec.end(), 1), vec.end()); // it is not specified which argument is evaluated first!!!!!!! } }
The last line of code only works if vec.end() is not changed (invalidated) before and after executing std::remove. This is important, because we do not know which argument is evaluated first.