Namespaces
Variants

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

Desde 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)

Ordenamiento y operaciones relacionadas
Operaciones de partición
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(sobre rangos particionados)
Operaciones de conjunto (sobre rangos ordenados)
Operaciones de fusión (sobre 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


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria (sobre rangos ordenados)
       
       
Operaciones de conjunto (sobre rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
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 = ranges::less >
constexpr ranges::minmax_result<const T&>
    minmax( const T& a, const T& b, Comp comp = {}, Proj proj = {} );
(1) (desde 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) (desde 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) (desde C++20)
Tipos auxiliares
template< class T >
using minmax_result = ranges::min_max_result<T>;
(4) (desde C++20)

Devuelve el menor y el mayor de los valores proyectados dados.

1) Devuelve referencias al menor y al mayor de a y b.
2) Devuelve el menor y el mayor de los valores en la lista de inicialización r.
3) Devuelve el menor y el mayor de los valores en el rango r.

Para las sobrecargas (2,3), el comportamiento no está definido si el rango está vacío (según lo determinado por ranges::distance(r)).

Las entidades similares a funciones descritas en esta página son objetos función de algoritmo (conocidos informalmente como niebloids), es decir:

Parámetros

a, b - los valores a comparar
r - un rango no vacío de valores a comparar
comp - comparación a aplicar a los elementos proyectados
proj - proyección a aplicar a los elementos

Valor de retorno

1) { b, a } si, de acuerdo con sus respectivos valores proyectados, b es menor que a ; de lo contrario devuelve { a, b } .
2,3) { s, l } , donde s y l son respectivamente los valores mínimo y máximo en r , según su valor proyectado. Si varios valores son equivalentes al mínimo y máximo, retorna el valor mínimo más a la izquierda, y el valor máximo más a la derecha. Si el rango está vacío (determinado por ranges:: distance ( r ) ), el comportamiento es indefinido.

Complejidad

1) Exactamente una comparación y dos aplicaciones de la proyección.
2,3) Como máximo 3 / 2 * ranges:: distance ( r ) comparaciones y el doble de aplicaciones de la proyección.

Implementación posible

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;

Notas

Para la sobrecarga (1) , si uno de los parámetros es un temporal, la referencia devuelta se convierte en una referencia colgante al final de la expresión completa que contiene la llamada a minmax :

int n = 1;
auto p = std::ranges::minmax(n, n + 1);
int m = p.min; // correcto
int x = p.max; // comportamiento indefinido
// Nótese que los enlaces estructurados presentan el mismo problema
auto [mm, xx] = std::ranges::minmax(n, n + 1);
xx; // comportamiento indefinido

Ejemplo

#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';
}

Salida posible:

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

Véase también

devuelve el menor de los valores dados
(objeto función de algoritmo)
devuelve el mayor de los valores dados
(objeto función de algoritmo)
devuelve los elementos más pequeño y más grande en un rango
(objeto función de algoritmo)
limita un valor entre un par de valores límite
(objeto función de algoritmo)
(C++11)
devuelve el menor y el mayor de dos elementos
(plantilla de función)