如何将模板化的取消引用迭代器类型简洁地表达为模板参数

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

假设我正在为 c++17 重写 std::min_element

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

我对所有的重载都不满意。如果 (1) 和 (3) 可以用默认参数表示,我会非常喜欢。

所以 (3) 可以用

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

我的问题是???涉及

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

我的意图是让一个专门的 std::less<MyType> 为任何取消引用 MyType 的迭代器和使用 MyType*.

的任何范围工作

随着过载,它就变成了

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

调用

 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
 }

有没有一种简洁的方法来删除默认参数的重载?

而且我认为我的版本有很多错误。

std::less<void> 对任何类型都有效,因为它的 operator() 是一个模板,要比较的实际类型是在调用运算符时推导出来的。它是在 C++14 中引入的。

如果你有一个迭代器类型,并且你想得到它的 reference 类型是什么,只需要询问特征 class: std::iterator_traits<Iterator>::reference。因为它是 C++20 之前的 ForwardIterator,所以它必须是对 value_type 的语言引用。所以你可以remove_reference就可以了,而且你有兴趣的类型。

C++20 甚至有一个方便的元函数,它或多或少做同样的事情(但它需要 C++20 概念化的迭代器):std::iter_reference_t<Iterator>。请注意,由于 C++20 前向迭代器允许代理迭代器(其中 reference 不必是 value_type&),您可能需要改用 iter_value_t<Iterator>