How to place objects that seem not be comparable in a C++ std::set?
algorithm, c++
Solution
I would recommend not implementing it as operator<, to avoid possible confusion, but rather pass the order function as a parameter to the std::set template argument.
struct server
{
std::string name;
int port;
};
struct name_then_port : public std::binary_function<server,server,bool>
{
bool operator()( server const & lhs, server const & rhs ) {
// using litb approach (more efficient as it does not call both < and == on strings:
int cmp = lhs.name.compare(rhs.name);
return ( cmp < 0 ) || ((cmp==0) && ( lhs.port < rhs.port));
}
};
struct port_then_name : public std::binary_function<server,server,bool>
{
bool operator()( server const & lhs, server const & rhs ) {
return (lhs.port < rhs.port) || ((lhs.port==rhs.port) && (lhs.name<rhs.name));
}
};
int main()
{
std::set< server, name_then_port > servers; // or:
std::set< server, port_then_name > servers2;
}
About the question of whether this problem has been identified before, it has. The general solution is exactly what you posted: lexicographical order. While the term is usually referred to string ordering, but the ordering is the same: take the first element, compare if it does not define an order take the next data element and iterate.
Problem
Suppose I want to put objects that identify a server into a stl `set`. Then I would have to make sure that I also implement `operator<` for these objects otherwise I would run into a compiler error: ``` struct ServerID { std::string name; // name of the server int port; }; std::set<ServerID> servers; // compiler error, no operator< defined ``` This is just one example of a common problem where I want to make an object comparable. My current solution usually goes like this: ``` bool operator< (const ServerID & lhs, const ServerID & rhs) { if (lhs.name != rhs.name) { return lhs.name < rhs.name; } else { return lhs.port < rhs.port; } } ``` This is just a solution that I found myself. But I suspect that this problem might also have been recognized in computer science. So if I'm lucky there is a better solution for this. Can anyone hint me towards that?