std::ranges::minmax, std::ranges::minmax_result
| Definiert in Header <algorithm> |
||
| Aufruf-Signatur |
||
| template< class T, class Proj = std::identity, std::indirect_strict_weak_order< |
(1) | (seit C++20) |
| template< std::copyable T, class Proj = std::identity, std::indirect_strict_weak_order< |
(2) | (seit C++20) |
| template< ranges::input_range R, class Proj = std::identity, std::indirect_strict_weak_order< |
(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.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.
- Können explizite Template-Argumentlisten bei keinem von ihnen angegeben werden.
- Keiner von ihnen ist für Argument-abhängige Suche sichtbar.
- Wenn einer von ihnen durch normale unqualifizierte Suche als Name links vom Funktionsaufrufoperator gefunden wird, wird die Argument-abhängige Suche unterdrückt.
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
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
[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
| (C++20) |
Gibt den kleineren der beiden Werte zurück (Algorithmus-Funktionsobjekt) |
| (C++20) |
Gibt den größeren der beiden Werte zurück (Algorithmus-Funktionsobjekt) |
| (C++20) |
gibt das kleinste und das größte Element in einem Bereich zurück (Algorithmus-Funktionsobjekt) |
| (C++20) |
klemmt einen Wert zwischen einem Paar von Grenzwerte (Algorithmus-Funktionsobjekt) |
| (C++11) |
gibt die kleinere und größere von zwei Elementen zurück (Funktionsvorlage) |