Piotr wrote:
My question is "For the first case, why we need to call c.erase() again
and pass in the return value of remove_if()?" Doesn't the call to
remove_if() remove the item from the container (in this case a vector)?
why we need to call erase() again?
Algorithms work on sequences designated by pairs of iterators. They do
not work on containers. remove_if "removes" elements from the sequence
that's passed to it by copying replacement elements on top of rejected
ones, and giving back a new end iterator that designates the end of the
new sequence. Typically that sequence is shorter than the original one,
and any elements pointed to by the end iterator and beyond are
irrelevant to the algorithm.
The algorithm doesn't know anything about the source of the sequence,
and cannot modify a container that might have been the source of the
sequence that was passed to it. But because it rearranges elements, you
can use the end iterator that it returns to tell you where the remaining
elements are in your container: they're the ones from the end iterator
returned by the algorithm to the actual end of the container. So you
erase 'em if that's appropriate.
If I haven't made too many typos, try this:
int data[] = { 1, 2, 3, 4, 5, 6, 7 }
struct is_odd
{
bool operator()(int val)
{
return val & 1;
}
};
int main()
{
int *begin = data;
int *end = data + sizeof(data) / sizeof(*data);
std::cout << "Original sequence: ";
std::copy(begin, end, std::ostream_iterator<int>(std::cout, " ");
std::cout << '\n';
int *new_end = std::remove_if(begin, end, is_odd());
// nothing to erase, 'cause the container's size is fixed
std::cout << "Modified sequence: ";
std::copy(begin, new_end, std::ostream_iterator<int>(std::cout, " ");
std::cout << '\n';
std::cout << "Original container: ";
std::copy(begin, end, std::ostream_iterator<int>(std::cout, " ");
std::cout << '\n';
return 0;
}
Now modify it to use a vector<int> instead of an array.
--
Pete Becker
Dinkumware, Ltd. (
http://www.dinkumware.com)