std::ranges::min_element(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::ranges::min_element(3) πŸ’…

okay so bestie, welcome to the C++ Standard Libary corner of the universe (yep, that’s how this page spells it, iykyk). We’re talking about the iconic range algorithm that finds the smallest element, and it’s giving main character energy. πŸ¦‹βœ¨

🌸 NAME 🌸

std::ranges::min_element β€” std::ranges::min_element

That’s the NAME section doing its little name thing. Periodt. πŸ’…

✨ Synopsis ✨

Defined in header <algorithm>.

πŸŽ€ Call signature πŸŽ€

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 = {} );

That one is (1) and it’s since C++20. 🫢

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 = {} );

That one is (2) and it’s also since C++20. ⭐

  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, that is:

  • Explicit template argument lists cannot be specified when calling any of them.
  • None of them are visible to argument-dependent lookup.
  • When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.

In practice, they may be implemented as function objects, or with special compiler extensions. 🧚

πŸŽ€ Parameters πŸŽ€

  • first, last β€” iterator-sentinel pair denoting the range to examine
  • r β€” the range to examine
  • 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 last if the range is empty (i.e., first == last). No cap, that’s the whole deal. 🌈

πŸ”₯ Complexity πŸ”₯

Exactly max(N - 1, 0) comparisons, where N = ranges::distance(first, last).

🧚 Possible implementation 🧚

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;
        while (++first != last)
            if (std::invoke(comp, std::invoke(proj, *first), std::invoke(proj, *smallest)))
                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;

🌟 Example 🌟

// Run this code

#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>

int main()
{
    namespace ranges = std::ranges;

    std::array v{3, 1, -13, 1, 3, 7, -13};

    auto iterator = ranges::min_element(v.begin(), v.end());
    auto position = ranges::distance(v.begin(), iterator);
    std::cout << "min element is v[" << position << "] == " << *iterator << '\n';

    auto abs_compare = [](int a, int b) { return (std::abs(a) < std::abs(b)); };
    iterator = ranges::min_element(v, abs_compare);
    position = ranges::distance(v.begin(), iterator);
    std::cout << "|min| element is v[" << position << "] == " << *iterator << '\n';
}

🌈 Output 🌈

min element is v[2] == -13
|min| element is v[1] == 1

πŸ‘‘ See also πŸ‘‘

  • ranges::max_element (C++20) β€” returns the largest element in a range (niebloid)
  • ranges::minmax_element (C++20) β€” returns the smallest and the largest elements in a range (niebloid)
  • ranges::max (C++20) β€” returns the greater of the given values (niebloid)
  • min_element β€” returns the smallest element in a range (function template)

kisses, cppreference.com πŸ’– β€” source http://cppreference.com, version/date 2024.06.10, page std::ranges::min_element(3). bye bestie, go find your minimum 🫢✨

πŸ“¦ where this page comes from