Spec-Zone.ru › C++

std::minmax

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

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

1,2) Возвращает ссылки на меньшее и большее из a и b.
1) Для сравнения значений используется operator<.
Если T не удовлетворяет требованиям LessThanComparable, поведение не определено.
2) Для сравнения значений используется функция сравнения comp.
3,4) Возвращает наименьшее и наибольшее значения из списка инициализации ilist.
Если ilist.size() равно нулю или T не удовлетворяет требованиям CopyConstructible, поведение не определено.
3) Для сравнения значений используется operator<.
Если T не удовлетворяет требованиям LessThanComparable, поведение не определено.
4) Для сравнения значений используется функция сравнения comp.

Параметры

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

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

boolcmp(constType1&a,constType2&b);

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

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

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) Ровно одно сравнение с использованием operator<.
2) Ровно одно применение функции сравнения comp.
3,4) Пусть \(\scriptsize N\)N — это ilist.size():
3) Не более \(\scriptsize \frac{3N}{2}\)3N/2 сравнений с использованием operator<.
4) Не более \(\scriptsize \frac{3N}{2}\)3N/2 применений функции сравнения comp.

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

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

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющих поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применён к Поведение согласно опубликованной версии Правильное поведение
LWG 2239 C++11 Для T требовалось соответствие требованиям LessThanComparable для перегрузок (2,4) не требуется

См. также

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

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

Spec-Zone.ru

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