In my other question, How to use a static method as a callback in c++, people solved my practical problem, then suggested I take a different approach in general to follow best practice. I would like a better understanding of why.
This example uses a comparator, but I would really like to understand if there is a general rule for functional programming (for example perhaps also aggregator functions related to a class etc.)
Example use case for a comparator function:
#include <set>
int main() {
std::set<MyClass, decltype(SOMETHING_HERE)> s(SOMETHING_HERE);
return 0;
}
Below are solutions I am aware of, from most to least recommended (I believe) - the opposite order to what I would currently choose.
1.
Recommended way (I believe) with a functor:
struct MyComparator {
bool operator() (MyClass a, MyClass b) const {
return a > b; // Reversed
}
};
std::set<MyClass, MyComparator)> s;
I don't like: verbose; not lexically tied to MyClass; I don't understand why s has no constructor argument. I am confused about the lack of argument because set
seems to mix up/combine deciding the comparison algorithm at compile time / with the typesystem (as in this example), and at runtime / with a pointer. If it was just one way or the other I would be fine with "that's just how it is".
2.
A method that seems nicer to me:
auto const my_comparator = [](int a, int b) {
return a > b;
};
std::set<int, decltype(my_comparator)> s(my_comparator);
It's terser. Intention is clear: it is a function, not a class that could be potentially added to. Passing the object, not just the type, makes sense to me (couldn't there be 2 different implementations).
3.
The method that makes most sense to me (based on other languages):
class MyClass {
public:
// More code here
static auto compare_reverse(MyClass a, MyClass b) {
return a > b;
}
};
std::set<int, decltype(&MyClass::compare_reverse)> s(&MyClass::compare_reverse);
It is clearly related (and lexically tied to) MyClass. Seems efficient (though I have been told it's not) and terse.
Any explanation why the recommended order is better, performance, bugs/maintainability, philosophical, very appreciated.