I have a set of pointers and I want the set to be sorted in a specific order.
I came up with this code and it works as expected:
#include <string>
#include <iostream>
#include <set>
class Data
{
public:
std::string name;
int data;
bool operator < (const Data& other) const
{
return name < other.name;
}
bool operator < (const Data* other) const
{
std::cout << "never called ";
return name < other->name;
}
};
struct DataComparator
{
bool operator()(const Data* lhs, const Data* rhs) const
{
return *lhs < *rhs;
}
};
int main() {
Data d1{ "bb", 1 };
Data d2{ "cc", 2 };
Data d3{ "aa", 3 };
std::set<Data*, DataComparator> s;
s.insert(&d1);
s.insert(&d2);
s.insert(&d3);
// print set members sorted by "name" field
for (auto& d : s)
std::cout << d->name << "\n";
return 0;
}
What bothers me is the fact that I need to use the DataComparator
struct in order to implement a custom sort order. I'd like the comparator be part of the Data
class. I tried to implement the bool operator < (const Data* other) const
class member and declare the set as std::set<Data*> s;
, but now the operator <
function is (unsurprisingly) never called and the sort order is by pointer address.
Is there some way to implement the custom comparator directly in the Data
class so I can just have this:
std::set<Data*> s;
...
// print set members sorted by "name" field
for (auto& d : s)
std::cout << d->name << "\n";
Is there some way to implement the custom comparator directly in the Data class so I can just have [stuff]:
No. I'd write a template
template <typename T>
struct PointerLess
{
bool operator()(const T * lhs, const T * rhs) const
{
return *lhs < *rhs;
}
};
Then you'd have std::set<Data*, PointerLess<Data>>
etc.