std::ranges::min_element() algorithm
- od C++20
- Simplified
- Detailed
// (1)
constexpr I min_element( I first, S last, Comp comp = {}, Proj proj = {} );
// (2)
constexpr ranges::borrowed_iterator_t<R>
min_element( R&& r, Comp comp = {}, Proj proj = {} );
The type of arguments are generic and have the following constraints:
I
-std::forward_iterator
S
-std::sentinel_for<I>
R
-std::ranges::forward_range
Comp
:- (1) -
std::indirect_strict_weak_order<std::projected<I, Proj>>
- (2) -
std::indirect_strict_weak_order<std::projected<ranges::iterator_t<R>, Proj>>
- (1) -
Proj
- (none)
The Proj
and Comp
template arguments have the following default types: std::identity
, ranges::less
for all overloads.
Additionally, each overload has the following constraints:
- (1) -
std::sortable<I, Comp, Proj>
- (2) -
std::sortable<ranges::iterator_t<R>, Comp, Proj>
// (1)
template<
std::forward_iterator I,
std::sentinel_for<I> S,
class Proj = std::identity,
std::indirect_strict_weak_order<std::projected<I, Proj>> Comp = ranges::less
>
constexpr I min_element( I first, S last, Comp comp = {}, Proj proj = {} );
// (2)
template<
ranges::forward_range R,
class Proj = std::identity,
std::indirect_strict_weak_order<std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less
>
constexpr ranges::borrowed_iterator_t<R>
min_element( R&& r, Comp comp = {}, Proj proj = {} );
-
(1) Finds the smallest element in the range [
first
;last
). -
(2) Same as (1), but uses
r
as the source range, as if usingranges::begin(r)
asfirst
andranges::end(r)
aslast
.
The function-like entities described on this page are niebloids.
Parameters
first last | The range to find the smallest value in. |
r | The range to find the smallest value in. |
comp | Comparison to apply to the projected elements. |
proj | Projection to apply to the elements. |
Return value
Iterator to the smallest element in the range [first
; last
).
If several elements in the range are equivalent to the smallest element, returns the iterator to the first such element.
Returns first
if the range is empty.
Complexity
Given N
as std::distance(first, last)
:
Exactly min(N - 1, 0)
comparisons.
Exceptions
(none)
Possible implementation
min_element(1) and min_element(2)
struct min_element_fn
{
template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirect_strict_weak_order<std::projected<I, Proj>> Comp = ranges::less>
constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const
{
if (first == last)
return last;
auto smallest = first;
++first;
for (; first != last; ++first)
if (!std::invoke(comp, std::invoke(proj, *smallest), std::invoke(proj, *first)))
smallest = first;
return smallest;
}
template<ranges::forward_range R, class Proj = std::identity,
std::indirect_strict_weak_order<
std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, Comp comp = {}, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::ref(comp), std::ref(proj));
}
};
inline constexpr min_element_fn min_element;
Examples
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v {3, 1, -14, 1, 5, 9};
namespace ranges = std::ranges;
auto result = ranges::min_element(v.begin(), v.end());
std::cout << "min element at [" << ranges::distance(v.begin(), result)
<< "]\n";
auto abs_compare = [](int a, int b) { return (std::abs(a) < std::abs(b)); };
result = ranges::min_element(v, abs_compare);
std::cout << "|min| element at [" << ranges::distance(v.begin(), result)
<< "]\n";
}
min element at [2]
|min| element at [1]
Hover to see the original license.