Define a function in function declaration using std::iterator traits and auto
The easy way to fix this is to not have a default function and instead have two overloads. This lets you get rid of using a std::function
, which is expensive, at the cost of writing a couple lines of boiler plate code. If you use
template<class ForwardIt, class Func>
void radix_sort(ForwardIt first, ForwardIt last, Func get_value) {
// ...
}
template<class ForwardIt>
void radix_sort(ForwardIt first, ForwardIt last) {
radix_sort(first, last, [](const typename std::iterator_traits<ForwardIt>::value_type& x){ return x; });
}
the you get the default "identity" with no function, and you get the exact function object otherwise if one is provided.
For the benefit of future users,
I would like to point out that C++20 introduces the class std::identity
,
which aids in solving the problem.
With its help,
the code can be rewritten as:
template <typename For, typename F = std::identity>
void radix_sort(For first, For end, F f = {})
{
/* ... */
}
And it is very easy to implement a standard-conforming one yourself if you don't have C++20, like this:
struct identity {
template <class T>
constexpr T&& operator()(T&& t) const noexcept
{
return std::forward<T>(t);
}
using is_transparent = void;
};