Code:
bool operator <(const DispatchInfo& di)const
{
return id <di.id && enumVal < di.enumVal && address < di.address;
}
This is what the map uses (it doesn't use operator==). If a < b == false and b < a == false then the items are equivalent. Given your operator< lots of objects are going to be treated as equivalent (and as the map stores only one of multiple equivalent items, you are going to see only one added).
The comparison function needs to be more complicated. For two values to compare it should look something like:
Code:
if (a.first < b.first) {
return true;
}
else if (!(b.first < a.first)) { //i.e a.first == b.first
return a.second < b.second;
}
return false;
And here's just for fun, some template metaprogramming that produces a comparator to compare using four members.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstdlib>
template <class F1, class F2>
class MultiCompareT
{
F1 fun1;
F2 fun2;
public:
MultiCompareT(F1 f1, F2 f2): fun1(f1), fun2(f2) {}
template <class T>
bool operator() (const T& a, const T& b)
{
return fun1(a, b) || (!fun1(b, a) && fun2(a, b));
}
template <class F3>
MultiCompareT<F1, MultiCompareT<F2, MultiCompareT<F3, void> > > then(F3 fun3)
{
return MultiCompareT<F1, MultiCompareT<F2, MultiCompareT<F3, void> > >(
fun1,
MultiCompareT<F2, MultiCompareT<F3, void> >(
fun2,
MultiCompareT<F3, void>(fun3)
)
);
}
};
template <class F>
class MultiCompareT<F, void>
{
F fun;
public:
MultiCompareT(F f): fun(f) {}
template <class T>
bool operator() (const T& a, const T& b)
{
return fun(a, b);
}
template <class F2>
MultiCompareT<F, MultiCompareT<F2, void> > then(F2 fun2)
{
return MultiCompareT<F, MultiCompareT<F2, void> >(fun, MultiCompareT<F2, void>(fun2));
}
};
template <class F>
MultiCompareT<F, void> MultiCompare(F fun)
{
return MultiCompareT<F, void>(fun);
};
template <class O, class T>
class CompareMemberT
{
T O::*ptr;
public:
CompareMemberT(T O::*ptr): ptr(ptr) {}
bool operator() (const O& a, const O& b) const
{
return (a.*ptr) < (b.*ptr);
}
};
template <class O, class T>
CompareMemberT<O, T> CompareMember(T O::*ptr)
{
return CompareMemberT<O, T>(ptr);
};
struct Test
{
unsigned u;
int i;
char c;
bool b;
};
std::ostream& operator<< (std::ostream& os, const Test& t)
{
return os << "(" << t.u << ", " << t.i << ", " << t.c << ", " << t.b << ")";
}
int main()
{
std::vector<Test> vec;
for (int i = 0; i != 44; ++i) {
Test t = { rand() % 8, rand() % 8, rand() % 4 + 'a', rand() % 2 };
vec.push_back(t);
}
std::sort(vec.begin(), vec.end(),
MultiCompare(CompareMember(&Test::u))
.then(CompareMember(&Test::i))
.then(CompareMember(&Test::c))
.then(CompareMember(&Test::b))
);
std::cout << std::boolalpha << '\n';
std::copy(vec.begin(), vec.end(), std::ostream_iterator<Test>(std::cout, "\n"));
}