std::ranges:: clamp
std::ranges
| Non-modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Partitioning operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sorting operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Binary search operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Heap operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Minimum/maximum operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Permutation operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fold operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Operations on uninitialized storage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Return types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definiert im Header
<algorithm>
|
||
|
Aufrufsignatur
|
||
|
template
<
class
T,
class
Proj
=
std::
identity
,
std::
indirect_strict_weak_order
<
std
::
projected
<
const
T
*
, Proj
>>
Comp
=
|
(seit C++20) | |
Wenn der Wert von
std::
invoke
(
proj, v
)
innerhalb des Intervalls
[
std::
invoke
(
proj, lo
)
,
std::
invoke
(
proj, hi
)
]
liegt, wird
v
zurückgegeben; andernfalls wird die nächstgelegene Grenze zurückgegeben.
Das Verhalten ist undefiniert, wenn std:: invoke ( proj, lo ) größer ist als std:: invoke ( proj, hi ) .
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithm Function Objects (informell bekannt als Niebloids ), das heißt:
- Explizite Template-Argumentlisten können beim Aufruf keiner von ihnen angegeben werden.
- Keiner von ihnen ist sichtbar für argument-dependent lookup .
- Wenn einer von ihnen durch normal unqualified lookup als Name links vom Funktionsaufrufoperator gefunden wird, wird argument-dependent lookup unterdrückt.
Inhaltsverzeichnis |
Parameter
| v | - | der zu beschränkende Wert |
| lo, hi | - | die Grenzen, auf die v beschränkt wird |
| comp | - | der Vergleich, der auf die projizierten Elemente angewendet wird |
| proj | - | die Projektion, die auf v , lo und hi angewendet wird |
Rückgabewert
Referenz auf lo , wenn der projizierte Wert von v kleiner ist als der projizierte Wert von lo , Referenz auf hi , wenn der projizierte Wert von hi kleiner ist als der projizierte Wert von v , andernfalls Referenz auf v .
Komplexität
Höchstens zwei Vergleiche und drei Anwendungen der Projektion.
Mögliche Implementierung
struct clamp_fn { template<class T, class Proj = std::identity, std::indirect_strict_weak_order<std::projected<const T*, Proj>> Comp = std::ranges::less> constexpr const T& operator()(const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {}) const { auto&& pv = std::invoke(proj, v); if (std::invoke(comp, std::forward<decltype(pv)>(pv), std::invoke(proj, lo))) return lo; if (std::invoke(comp, std::invoke(proj, hi), std::forward<decltype(pv)>(pv))) return hi; return v; } }; inline constexpr clamp_fn clamp; |
`-Tags wurde gemäß den Anforderungen nicht übersetzt, da er technische Programmiersprache enthält. Die HTML-Struktur und -Attribute bleiben ebenfalls unverändert.
Hinweise
std::ranges::clamp
by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned:
int n = -1; const int& r = std::ranges::clamp(n, 0, 255); // r ist hängend
Wenn v äquivalent zu einer der Grenzen verglichen wird, wird eine Referenz auf v zurückgegeben, nicht auf die Grenze.
Diese Funktion sollte nicht mit einer Projektion, die per Wert zurückgibt, und einem Komparator, der Argumente per Wert nimmt, verwendet werden, es sei denn, ein Move vom Ergebnistyp der Projektion zum Parameter des Komparators entspricht einem Copy. Wenn der Vergleich mittels
std::invoke
das Ergebnis der Projektion ändern würde, ist das Verhalten aufgrund
der semantischen Anforderungen von
std::regular_invocable
(subsumiert durch
std::indirect_strict_weak_order
) undefiniert.
Der Standard erfordert, dass die Wertkategorie des Ergebnisses der Projektion erhalten bleibt, und proj darf nur einmal auf v aufgerufen werden, was bedeutet, dass ein Projektergebnis, das ein Prvalue ist, zwischengespeichert und zweimal für die beiden Aufrufe des Comparators verschoben werden muss.
- libstdc++ entspricht nicht dieser Vorgabe und übergibt das Projektionsergebnis stets als Lvalue.
- libc++ führte die Projektion früher zweimal aus, was in Clang 18 korrigiert wurde.
- MSVC STL führte die Projektion früher zweimal aus, was in VS 2022 17.2 korrigiert wurde.
Beispiel
#include <algorithm> #include <cstdint> #include <iomanip> #include <iostream> #include <string> using namespace std::literals; namespace ranges = std::ranges; int main() { std::cout << "[raw] [" << INT8_MIN << ',' << INT8_MAX << "] " "[0" << ',' << UINT8_MAX << "]\n"; for (int const v : {-129, -128, -1, 0, 42, 127, 128, 255, 256}) std::cout << std::setw(4) << v << std::setw(11) << ranges::clamp(v, INT8_MIN, INT8_MAX) << std::setw(8) << ranges::clamp(v, 0, UINT8_MAX) << '\n'; std::cout << std::string(23, '-') << '\n'; // Projektionsfunktion const auto stoi = [](std::string s) { return std::stoi(s); }; // Wie oben, aber mit Strings for (std::string const v : {"-129", "-128", "-1", "0", "42", "127", "128", "255", "256"}) std::cout << std::setw(4) << v << std::setw(11) << ranges::clamp(v, "-128"s, "127"s, {}, stoi) << std::setw(8) << ranges::clamp(v, "0"s, "255"s, {}, stoi) << '\n'; }
Ausgabe:
[raw] [-128,127] [0,255] -129 -128 0 -128 -128 0 -1 -1 0 0 0 0 42 42 42 127 127 127 128 127 128 255 127 255 256 127 255 ----------------------- -129 -128 0 -128 -128 0 -1 -1 0 0 0 0 42 42 42 127 127 127 128 127 128 255 127 255 256 127 255
Siehe auch
|
(C++20)
|
gibt den kleineren der gegebenen Werte zurück
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
gibt den größeren der gegebenen Werte zurück
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
prüft, ob ein ganzzahliger Wert im Wertebereich eines gegebenen Ganzzahltyps liegt
(Funktionstemplate) |
|
(C++17)
|
begrenzt einen Wert zwischen einem Paar von Grenzwerten
(Funktionstemplate) |