Skip to main content

std::ranges::min_element() algorithm

// (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>>
  • 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) Finds the smallest element in the range [first; last).

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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

Main.cpp
#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";
}
Output
min element at [2]
|min| element at [1]
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::min_element() algorithm

// (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>>
  • 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) Finds the smallest element in the range [first; last).

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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

Main.cpp
#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";
}
Output
min element at [2]
|min| element at [1]
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.