I have a map with a struct as key, I have overloaded the < operator, but the map is storing each entry as separate keys even though they are same. The code is as follows:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct vertex
{
int color;
vertex *pi;
int index;
bool operator<(const vertex & v ) const {
return this->index < v.index;
}
bool operator==(const vertex & v) const {
return this->index == v.index;
}
};
int main()
{
int x, y, num_edges;
vector<vertex* > v;
vertex *temp1, *temp2, *temp;
map<vertex*, vector<vertex*> > m;
map<vertex*, vector<vertex*> >::iterator it;
cout << "\nEnter no. of edges: ";
cin >> num_edges;
for( int i = 0; i < num_edges; i++ )
{
cout << "\nEnter source: ";
cin >> x;
cout << "\nEnter dest: ";
cin >> y;
temp1 = new vertex;
temp2 = new vertex;
temp1->index = x;
temp2->index = y;
m[temp1].push_back(temp2);
m[temp2].push_back(temp1);
}
temp1 = new vertex;
temp2 = new vertex;
cout << "\nPrinting map: " << endl;
for( it = m.begin(); it != m.end(); it++ )
{
temp = (*it).first;
cout << temp->index << "\t";
v = (*it).second;
for( int i = 0; i < v.size(); i++ )
{
temp1 = v[i];
cout << temp1->index << "\t";
}
cout << "\n";
v.clear();
}
for( it = m.begin(); it != m.end(); it++ )
{
temp = (*it).first;
v.push_back(temp);
}
return 0;
}
The output that I am getting now is:
Enter no. of edges: 4
Enter source: 1
Enter dest: 3
Enter source: 4
Enter dest: 3
Enter source: 4
Enter dest: 2
Enter source: 2
Enter dest: 1
Printing map:
1 3
3 1
4 3
3 4
4 2
2 4
2 1
1 2
But it should be:
1 3 2
2 4 1
3 1 4
4 3 2
Where am I going wrong?
The std::map will compare the type you give it as key (
vertex*), but you define the<operator on vertex.You can use the struct themselves as keys, or -if you have to use pointers- you have to give the map a way to compare the pointers.
Now,
std::mapuse thestd::lessas a comparison predicate, that is defined in therm of<(that’s why using the struct themselves, you can achieve the result by overloading<).You can either:
o) define yourself a predicate that compares vertex*: it can be
and then define you map as
o) specialize the std::less for vertex* as
and declare your map as
as usual.
I personally prefer the first (gives a more localized code, less “arcane” in future readings)