Namespaces
Variants

std::clamp

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p.ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenamiento y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de fusión (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Definido en el encabezado <algorithm>
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
(1) (desde C++17)
template< class T, class Compare >
constexpr const T& clamp( const T& v, const T& lo, const T& hi,
                          Compare comp );
(2) (desde C++17)

Si el valor de v está dentro de [lo, hi], devuelve v; en caso contrario, devuelve el límite más cercano.

1) Utiliza operator<(hasta C++20)std::less{}(desde C++20) para comparar los valores.
Si T no es LessThanComparable, el comportamiento no está definido.[1]
2) Utiliza la función de comparación comp para comparar los valores.

Si lo es mayor que hi, el comportamiento no está definido.

  1. ↑ Si se evita NaN, T puede ser un tipo de punto flotante.

Parámetros

v - el valor a acotar
lo, hi - los límites entre los que acotar v
comp - objeto función de comparación (es decir, un objeto que satisface los requisitos de Compare) que devuelve true si el primer argumento es menor que el segundo.

La firma de la función de comparación debe ser equivalente a la siguiente:

bool cmp(const Type1& a, const Type2& b);

Aunque la firma no necesita tener const&, la función no debe modificar los objetos que se le pasan y debe ser capaz de aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1& no está permitida, ni Type1 a menos que para Type1 un movimiento sea equivalente a una copia(desde C++11)).
Los tipos Type1 y Type2 deben ser tales que un objeto de tipo T pueda convertirse implícitamente a ambos.

Valor de retorno

Referencia a lo si v es menor que lo, referencia a hi si hi es menor que v, en caso contrario referencia a v.

Complejidad

1) Como máximo dos comparaciones usando operator<(hasta C++20)std::less{}(desde C++20).
2) Como máximo dos aplicaciones de la función de comparación comp.

Posible implementación

clamp (1)
template<class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
{
    return clamp(v, lo, hi, less{});
}
clamp (2)
template<class T, class Compare>
constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp)
{
    return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
}

Notas

Capturar el resultado de std::clamp por referencia produce una referencia colgante si uno de los parámetros es un temporal y ese parámetro se devuelve:

int n = -1;
const int& r = std::clamp(n, 0, 255); // r is dangling

Si v compara equivalente a cualquiera de los límites, devuelve una referencia a v, no al límite.

Macro de prueba de característica Valor Std Característica
__cpp_lib_clamp 201603L (C++17) std::clamp

Ejemplo

#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>

int main()
{
    std::cout << "[raw] "
                 "[" << INT8_MIN << ',' << INT8_MAX << "] "
                 "[0," << UINT8_MAX << "]\n";

    for (const int v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
        std::cout << std::setw(4) << v
                  << std::setw(11) << std::clamp(v, INT8_MIN, INT8_MAX)
                  << std::setw(8) << std::clamp(v, 0, UINT8_MAX) << '\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

Véase también

devuelve el menor de los valores dados
(plantilla de función & objeto función de algoritmo)
devuelve el mayor de los valores dados
(plantilla de función & objeto función de algoritmo)
(C++20)
comprueba si un valor entero está en el rango de un tipo entero dado
(plantilla de función)
acota un valor entre un par de valores límite
(objeto función de algoritmo)