Home > database >  How do I consicely express the templated dereferenced Iterator type as a template parameter
How do I consicely express the templated dereferenced Iterator type as a template parameter

Time:11-27

Lets say I'm rewriting std::min_element for c 17.

https://en.cppreference.com/w/cpp/algorithm/min_element

I'm unhappy with all the overloads. I'd very much like it if (1) and (3) could be expressed in terms of default arguments.

So (3) could replace (1) with

template< class ForwardIt, class Compare = typename std::less< ??? >  >
ForwardIt min_element( ForwardIt first, ForwardIt last, Compare comp = Compare{});

My problem is ??? involves

std::remove_reference<decltype((*first){})>.type

My intent is to have a specialized std::less<MyType> working for any iterator dereferencing to MyType and any range using MyType*.

With the overload it just becomes

 template<typename It>
 It min_element(It first, It last){
 {  auto e = *first;
    return min_element(first, last, std::less<decltype(e)>());
 }

calling the

 template<typename It, typename Comp>
 It min_element(It first, It last, Comp c){
 {  // it probably needs to be something here, maybe returning an It
 }

Is there a concise way to remove the overload with default arguments?

Also I imagine my version to be very buggy.

CodePudding user response:

std::less<void> does work for any type, because its operator() is a template and the actual type to be compared is deduced when the operator is called. It was introduced in C 14.

CodePudding user response:

If you have an iterator type, and you want to get what its reference type is, just ask the traits class: std::iterator_traits<Iterator>::reference. And since it's a pre-C 20 ForwardIterator, this is required to be a language reference to value_type. So you can just remove_reference on it, and you have the type of interest.

C 20 even has a convenient metafunction that does more-or-less the same thing (but it requires C 20-conceptualized iterators): std::iter_reference_t<Iterator>. Note that since C 20 forward iterators allow proxy iterators (where reference does not have to be value_type&), you may need to use iter_value_t<Iterator> instead.

  • Related