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;
};

Tags:

C++

C++11