Functors in C++ do not traditionally share a type. This makes it easy for the compiler to understand exactly which functor is being called, and causes a performance boost.
There is a mechanism in C++ called type erasure. This is where you forget what makes two types different, and only remembers what makes them the same.
The most common kind of type erasure in C++ is std::function
. This function here type erases a stateless template that takes two T const&
and returns a bool
:
template<class T, template<class...>class Z>
std::function< bool(T const&, T const&) >
comp() { return Z<T>{}; }
we can then take your code and do this:
uchar *itr = std::upper_bound(start, end, uchar(20),
cond? comp<uchar, std::greater>() : comp<uchar, std::less>());
or alternatively:
template<class T>
using comp_sig = bool(T const&, T const&);
template<class T, template<class...>class Z>
comp_sig<T>* comp() {
return [](T const& lhs, T const& rhs)->bool{
return Z<T>{}(lhs, rhs);
};
}
which gives you function pointers that call less
or greater
as required. This version might be slightly easier for compilers to optimize than the std::function
one, as compilers are really good at optimizing constant function pointers.