Spec-Zone.ru › C++

std::minmax

Определено в заголовке <algorithm>
(1)
template< class T >
std::pair<const T&, const T&> minmax( const T& a, const T& b );
(с C++11)
(до C++14)
template< class T >
constexpr std::pair<const T&, const T&> minmax( const T& a, const T& b );
(с C++14)
(2)
template< class T, class Compare >
std::pair<const T&, const T&> minmax( const T& a, const T& b,
                                      Compare comp );
(с C++11)
(до C++14)
template< class T, class Compare >
constexpr std::pair<const T&, const T&> minmax( const T& a, const T& b,
                                                Compare comp );
(с C++14)
(3)
template< class T >
std::pair<T, T> minmax( std::initializer_list<T> ilist );
(с C++11)
(до C++14)
template< class T >
constexpr std::pair<T, T> minmax( std::initializer_list<T> ilist );
(с C++14)
(4)
template< class T, class Compare >
std::pair<T, T> minmax( std::initializer_list<T> ilist, Compare comp );
(с C++11)
(до C++14)
template< class T, class Compare >
constexpr std::pair<T, T> minmax( std::initializer_list<T> ilist, Compare comp );
(с C++14)

Возвращает наименьшее и наибольшее из заданных значений.

1,2) Возвращает ссылки на меньшее и большее из a и b.
3,4) Возвращает наименьшее и наибольшее из значений в списке инициализации ilist.

Версии (1,3) используют operator< для сравнения значений, в то время как версии (2,4) используют заданную функцию сравнения comp.

Параметры

a, b - сравниваемые значения
ilist - список инициализации со значениями для сравнения
comp - объект функции сравнения (т.е. объект, удовлетворяющий требованиям Compare), который возвращает true, если первый аргумент меньше второго.

Подпись функции сравнения должна быть эквивалентна следующему:

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

Хотя подпись не обязательно должна содержать const&, функция не должна изменять объекты, переданные ей, и должна быть способна принимать все значения типа (возможно, const) Type1 и Type2 независимо от категории значения (следовательно, Type1& недопустимо, а также Type1 за исключением случаев, когда для Type1 перемещение эквивалентно копированию(с C++11)).
Типы Type1 и Type2 должны быть такими, чтобы объект типа T можно было неявно преобразовать в оба из них.

Требования к типу
-T должен удовлетворять требованиям LessThanComparable для использования перегрузок (1,3).
-T должен удовлетворять требованиям CopyConstructible для использования перегрузок (3,4).

Возвращаемое значение

1,2) Возвращает результат std::pair<const T&, const T&>(a, b) , если a < b или если a эквивалентно b. Возвращает результат std::pair<const T&, const T&>(b, a) , если b < a.
3,4) Пара с наименьшим значением в ilist в качестве первого элемента и наибольшим в качестве второго. Если несколько элементов эквивалентны наименьшему, возвращается самый левый такой элемент. Если несколько элементов эквивалентны наибольшему, возвращается самый правый такой элемент.

Сложность

1,2) Ровно одно сравнение.
3,4) Не более ilist.size() * 3 / 2 сравнений.

Возможная реализация

minmax (1)
template<class T>
constexpr std::pair<const T&, const T&> minmax(const T& a, const T& b)
{
    return (b < a) ? std::pair<const T&, const T&>(b, a)
                   : std::pair<const T&, const T&>(a, b);
}
minmax (2)
template<class T, class Compare>
constexpr std::pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp)
{
    return comp(b, a) ? std::pair<const T&, const T&>(b, a)
                      : std::pair<const T&, const T&>(a, b);
}
minmax (3)
template<class T>
constexpr std::pair<T, T> minmax(std::initializer_list<T> ilist)
{
    auto p = std::minmax_element(ilist.begin(), ilist.end());
    return std::pair(*p.first, *p.second);
}
minmax (4)
template<class T, class Compare>
constexpr std::pair<T, T> minmax(std::initializer_list<T> ilist, Compare comp)
{
    auto p = std::minmax_element(ilist.begin(), ilist.end(), comp);
    return std::pair(*p.first, *p.second);
}

Примечания

Для перегрузок (1,2), если один из параметров является временным, ссылка, возвращаемая, становится висячей ссылкой в конце полного выражения, содержащего вызов minmax:

int n = 1;
auto p = std::minmax(n, n + 1);
int m = p.first; // ok
int x = p.second; // undefined behavior
 
// Note that structured bindings have the same issue
auto [mm, xx] = std::minmax(n, n + 1);
xx; // undefined behavior

Пример

#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v{3, 1, 4, 1, 5, 9, 2, 6};
    std::srand(std::time(0));
    std::pair<int, int> bounds = std::minmax(std::rand() % v.size(),
                                             std::rand() % v.size());
 
    std::cout << "v[" << bounds.first << "," << bounds.second << "]: ";
    for (int i = bounds.first; i < bounds.second; ++i)
        std::cout << v[i] << ' ';
    std::cout << '\n';
}

Возможный вывод:

v[2,7]: 4 1 5 9 2

См. также

min
возвращает меньшее из заданных значений
(шаблон функции)
max
возвращает большее из заданных значений
(шаблон функции)
minmax_element
(C++11)
возвращает наименьшие и наибольшие элементы в диапазоне
(шаблон функции)
ranges::minmax
(C++20)
возвращает меньшее и большее из двух элементов
(niebloid)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/minmax

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API