Suppose I have a set (or map) of strings, and I want to use a custom comparator that compares only the first 5 characters. So "abcde" and "abcdef" are the same in my set.
typedef std::set<std::string, Cmp> MySet;
What is the best way to write Cmp?
The obvious way is like this:
struct Cmp
{
bool operator()(const string& x, const string& y)
{
return (x.substr(0, 5) < y.substr(0, 5));
}
}
The problem is that this code repeats .substr(0, 5)
. In this example it's pretty short, but in the general case it could be longer. I want to avoid this repeating code.
In general, given the types T1, T2
and the function T2 key(T1& const)
, I want a set of T1
elements that compares according to key(a) < key(b)
, where comparison on T2
is already well-defined. What is the best way to write this? I thought about writing a new class KeyBaseSet
, but that would be over-designing for my single use-case. Is there some way to do this using std
or Boost?
I'm looking for something similar to the key
argument when sorting in Python (https://docs.python.org/3/howto/sorting.html#key-functions), or the compare `on`
idiom in Haskell (https://stackoverflow.com/a/2788262/351105).