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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definido en el encabezado
<algorithm>
|
||
|
Firma de llamada
|
||
|
template
<
class
T,
class
Proj
=
std::
identity
,
std::
indirect_strict_weak_order
<
std
::
projected
<
const
T
*
, Proj
>>
Comp
=
|
(desde C++20) | |
Si el valor de
std::
invoke
(
proj, v
)
está dentro del rango
[
std::
invoke
(
proj, lo
)
,
std::
invoke
(
proj, hi
)
]
, devuelve
v
; de lo contrario, devuelve el límite más cercano.
El comportamiento es indefinido si std:: invoke ( proj, lo ) es mayor que std:: invoke ( proj, hi ) .
Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:
- No se pueden especificar listas de argumentos de plantilla explícitas al llamar a cualquiera de ellos.
- Ninguno de ellos es visible para la búsqueda dependiente de argumento .
- Cuando cualquiera de ellos es encontrado mediante la búsqueda no calificada normal como el nombre a la izquierda del operador de llamada de función, la búsqueda dependiente de argumento queda inhibida.
Contenidos |
Parámetros
| v | - | el valor a limitar |
| lo, hi | - | los límites para limitar v a |
| comp | - | la comparación a aplicar a los elementos proyectados |
| proj | - | la proyección a aplicar a v , lo y hi |
Valor de retorno
Referencia a lo si el valor proyectado de v es menor que el valor proyectado de lo , referencia a hi si el valor proyectado de hi es menor que el valor proyectado de v , de lo contrario referencia a v .
Complejidad
Como máximo dos comparaciones y tres aplicaciones de la proyección.
Implementación posible
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; |
Notas
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 está colgando
Si v se compara como equivalente a cualquiera de los límites, devuelve una referencia a v , no al límite.
Esta función no debe utilizarse con una proyección que retorna por valor y un comparador que toma argumentos por valor a menos que un movimiento desde el tipo de resultado de la proyección al tipo de parámetro del comparador sea equivalente a una copia. Si la comparación mediante
std::invoke
pudiera cambiar el resultado de la proyección, el comportamiento es indefinido debido a
los requisitos semánticos de
std::regular_invocable
(subsumidos por
std::indirect_strict_weak_order
).
El estándar requiere que se preserve la categoría de valor del resultado de la proyección, y proj solo puede ser invocado sobre v una vez, lo que significa que un resultado de proyección que es un prvalue debe ser almacenado en caché y movido dos veces para las dos invocaciones al comparador.
- libstdc++ no cumple con esto y siempre pasa el resultado de la proyección como un lvalue.
- libc++ solía ejecutar la proyección dos veces, lo cual fue corregido en Clang 18.
- MSVC STL solía ejecutar la proyección dos veces, lo cual fue corregido en VS 2022 17.2.
Ejemplo
#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'; // Función de proyección const auto stoi = [](std::string s) { return std::stoi(s); }; // Igual que arriba, pero con cadenas 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'; }
Salida:
[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
Véase también
|
(C++20)
|
devuelve el menor de los valores dados
(objeto función de algoritmo) |
|
(C++20)
|
devuelve el mayor de los valores dados
(objeto función de algoritmo) |
|
(C++20)
|
verifica si un valor entero está en el rango de un tipo entero dado
(plantilla de función) |
|
(C++17)
|
limita un valor entre un par de valores límite
(plantilla de función) |