Namensräume
Varianten
Aktionen

std::ranges::minmax, std::ranges::minmax_result

Von cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namespace std::ranges
Nicht-modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
       
       
minmax
Permutationsoperationen
Faltoperationen
Operationen auf uninitialisiertem Speicher
Rückgabetypen
 
Definiert in Header <algorithm>
Aufruf-Signatur
template< class T, class Proj = std::identity,

          std::indirect_strict_weak_order<
              std::projected<const T*, Proj>> Comp = ranges::less >
constexpr ranges::minmax_result<const T&>

    minmax( const T& a, const T& b, Comp comp = {}, Proj proj = {} );
(1) (seit C++20)
template< std::copyable T, class Proj = std::identity,

          std::indirect_strict_weak_order<
              std::projected<const T*, Proj>> Comp = ranges::less >
constexpr ranges::minmax_result<T>

    minmax( std::initializer_list<T> r, Comp comp = {}, Proj proj = {} );
(2) (seit C++20)
template< ranges::input_range R, class Proj = std::identity,

          std::indirect_strict_weak_order<
              std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less >
requires std::indirectly_copyable_storable<ranges::iterator_t<R>, ranges::range_value_t<R>*>
constexpr ranges::minmax_result<ranges::range_value_t<R>>

    minmax( R&& r, Comp comp = {}, Proj proj = {} );
(3) (seit C++20)
Hilfstypen
template< class T >
using minmax_result = ranges::min_max_result<T>;
(4) (seit C++20)

Gibt die kleinsten und größten der gegebenen projizierten Werte zurück.

1) Gibt Referenzen auf den kleineren und den größeren der Werte a und b zurück.
2) Gibt die kleinsten und größten Werte in der Initialisierungsliste r zurück.
3) Gibt die kleinsten und größten Werte im Bereich r zurück.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.

Inhalt

[edit] Parameter

a, b - die zu vergleichenden Werte
r - Ein nicht-leerer Bereich von zu vergleichenden Werten
comp - Vergleich, der auf die projizierten Elemente angewendet wird
proj - Projektion, die auf die Elemente angewendet wird

[edit] Rückgabewert

1) {b, a}, wenn gemäß ihrem projizierten Wert b kleiner ist als a; andernfalls gibt es {a, b} zurück.
2,3) {s, l}, wobei s und l die kleinsten bzw. größten Werte in r gemäß ihrem projizierten Wert sind. Wenn mehrere Werte dem kleinsten und größten entsprechen, wird der linkeste kleinste Wert und der rechteste größte Wert zurückgegeben. Wenn der Bereich leer ist (bestimmt durch ranges::distance(r)), ist das Verhalten undefiniert.

[edit] Komplexität

1) Genau ein Vergleich und zwei Anwendungen der Projektion.
2,3) Höchstens 3 / 2 * ranges::distance(r) Vergleiche und doppelt so viele Anwendungen der Projektion.

[edit] Mögliche Implementierung

struct minmax_fn
{
    template<class T, class Proj = std::identity,
             std::indirect_strict_weak_order<
                 std::projected<const T*, Proj>> Comp = ranges::less>
    constexpr ranges::minmax_result<const T&>
         operator()(const T& a, const T& b, Comp comp = {}, Proj proj = {}) const
    {
        if (std::invoke(comp, std::invoke(proj, b), std::invoke(proj, a)))
            return {b, a};
 
        return {a, b};
    }
 
    template<std::copyable T, class Proj = std::identity,
             std::indirect_strict_weak_order<
                 std::projected<const T*, Proj>> Comp = ranges::less>
    constexpr ranges::minmax_result<T>
        operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {}) const
    {
        auto result = ranges::minmax_element(r, std::ref(comp), std::ref(proj));
        return {*result.min, *result.max};
    }
 
    template<ranges::input_range R, class Proj = std::identity,
             std::indirect_strict_weak_order<
                 std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less>
    requires std::indirectly_copyable_storable<ranges::iterator_t<R>,
                                               ranges::range_value_t<R>*>
    constexpr ranges::minmax_result<ranges::range_value_t<R>>
        operator()(R&& r, Comp comp = {}, Proj proj = {}) const
    {
        auto result = ranges::minmax_element(r, std::ref(comp), std::ref(proj));
        return {std::move(*result.min), std::move(*result.max)};
    }
};
 
inline constexpr minmax_fn minmax;

[edit] Hinweise

Für Überladung (1), wenn einer der Parameter ein temporärer Wert ist, wird die zurückgegebene Referenz zu einer "dangling reference" (hängenden Referenz) am Ende des vollständigen Ausdrucks, der den Aufruf von minmax enthält.

int n = 1;
auto p = std::ranges::minmax(n, n + 1);
int m = p.min; // ok
int x = p.max; // undefined behavior
 
// Note that structured bindings have the same issue
auto [mm, xx] = std::ranges::minmax(n, n + 1);
xx; // undefined behavior

[edit] Beispiel

#include <algorithm>
#include <array>
#include <iostream>
#include <random>
 
int main()
{
    namespace ranges = std::ranges;
 
    constexpr std::array v{3, 1, 4, 1, 5, 9, 2, 6, 5};
 
    std::random_device rd;
    std::mt19937_64 generator(rd());
    std::uniform_int_distribution<> distribution(0, ranges::distance(v)); // [0..9]
 
    // auto bounds = ranges::minmax(distribution(generator), distribution(generator));
    // UB: dangling references: bounds.min and bounds.max have the type `const int&`.
 
    const int x1 = distribution(generator);
    const int x2 = distribution(generator);
    auto bounds = ranges::minmax(x1, x2); // OK: got references to lvalues x1 and x2
 
    std::cout << "v[" << bounds.min << ":" << bounds.max << "]: ";
    for (int i = bounds.min; i < bounds.max; ++i)
        std::cout << v[i] << ' ';
    std::cout << '\n';
 
    auto [min, max] = ranges::minmax(v);
    std::cout << "smallest: " << min << ", " << "largest: " << max << '\n';
}

Mögliche Ausgabe

v[3:9]: 1 5 9 2 6 5 
smallest: 1, largest: 9

[edit] Siehe auch

Gibt den kleineren der beiden Werte zurück
(Algorithmus-Funktionsobjekt)[bearbeiten]
Gibt den größeren der beiden Werte zurück
(Algorithmus-Funktionsobjekt)[edit]
gibt das kleinste und das größte Element in einem Bereich zurück
(Algorithmus-Funktionsobjekt)[bearbeiten]
klemmt einen Wert zwischen einem Paar von Grenzwerte
(Algorithmus-Funktionsobjekt)[bearbeiten]
(C++11)
gibt die kleinere und größere von zwei Elementen zurück
(Funktionsvorlage) [editieren]