Reputation: 2086
I'm just messing around with some lambda expressions and I decided to attempt to remove duplicate elements from a vector. However, it isn't working. I put in some debug logging and it appears that std::count isn't returning the expected result. Any would would be greatly appreciated.
For reference, I know this isn't the most efficient way to remove an item from a vector! I was just experimenting with lambdas as I don't understand them as well as I would like to.
Thanks!
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v = { 0, 0, 1, 2, 4, 4, 4 };
std::remove_if(v.begin(), v.end(), [&v](const int &x)
{
return std::count(v.begin(), v.end(), x) > 1;
});
std::cout << "\n\nResult:\n";
for (const auto& i : v) { std::cout << i << std::endl; }
return 0;
}
Upvotes: 2
Views: 3193
Reputation: 303206
That's because remove_if
doesn't actually remove elements:
Removing is done by shifting (by means of move assignment) the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range.
That's why it returns an iterator, so you can then:
A call to remove is typically followed by a call to a container's erase method, which erases the unspecified values and reduces the physical size of the container to match its new logical size.
That is:
v.erase(std::remove_if(v.begin(), v.end(), [&v](const int &x)
{
return std::count(v.begin(), v.end(), x) > 1;
}), v.end());
This is known as the Erase-remove idiom.
Note that if all you want to do is remove duplicates, and you don't care about preserving the order, you could use std::sort
and std::unique
(you need to sort
because unique
only "removes" consecutive duplicate elements):
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
Upvotes: 4