I'm trying to use the C++ Standard Library algorithm unique
(with BinaryPredicate
).
I've created a vector of pairs; each pair is like "(first=a vector of 4 doubles, second=an integer)". The second element serves as index so after using `unique, I can still tell the original index.
In the example below, I've created something like this:
10 20 30 40, 1
10 20 30 40, 2
10 20 30 40, 3
10 20 30 40, 4
10 20 30 40, 5
10 20 30 40, 6
Now I want to use the unique function to compare only the first element of each pair. I've used a customize binary predictor uniquepred
. Indeed, it works, but the vector is not reduced after using unique
.
Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=1
Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=6
Minimum working example follows. Please help me debugging this.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef std::vector<double> V1db;
typedef std::pair<V1db, int > Pairs;
typedef std::vector<Pairs> Vpairs;
bool uniquepred( const Pairs& l, const Pairs& r) {
if (l.first==r.first)
cout<<"equal!"<<endl;
return l.first == r.first;
}
int main()
{
Vpairs ak;
V1db u2(4);
u2[0]=10;u2[1]=20;u2[2]=30;u2[3]=40;
Pairs m2;
m2.first = u2;
m2.second= 1;
ak.push_back(m2);
m2.second= 2;
ak.push_back(m2);
m2.second= 3;
ak.push_back(m2);
m2.second= 4;
ak.push_back(m2);
m2.second= 5;
ak.push_back(m2);
m2.second= 6;
ak.push_back(m2);
cout<<"Size before="<<ak.size()<<endl;
unique(ak.begin(), ak.end(), uniquepred);
cout<<"Size after="<<ak.size()<<endl;
return 0;
}
You want to do:
ak.erase(unique(ak.begin(), ak.end(), uniquepred), ak.end());
The reason for this is that std::unique
reorders the values. It doesn't delete them though and you are left with a new range, from begin()
to the iterator that unique
returns. The container itself is not altered, other than this reordering.
There's no "remove at position X" method on vectors, even if there was it would invalidate the iterators. The unique
algorithm by design doesn't even know anything about the underlying container, so it can work with any valid pair of iterators. The only requirement is that they are ForwardIterators
.