名稱空間
變體
操作

std::minmax

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
minmax
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
未初始化記憶體上的操作
 
定義於標頭檔案 <algorithm>
template< class T >
std::pair<const T&, const T&> minmax( const T& a, const T& b );
(1) (C++11 起)
(C++14 起為 constexpr)
template< class T, class Compare >

std::pair<const T&, const T&> minmax( const T& a, const T& b,

                                      Compare comp );
(2) (C++11 起)
(C++14 起為 constexpr)
template< class T >
std::pair<T, T> minmax( std::initializer_list<T> ilist );
(3) (C++11 起)
(C++14 起為 constexpr)
template< class T, class Compare >

std::pair<T, T> minmax( std::initializer_list<T> ilist,

                        Compare comp );
(4) (C++11 起)
(C++14 起為 constexpr)

返回給定值中的最小值和最大值。

1,2) 返回 ab 中較小和較大的值的引用。
1) 使用 operator< 比較值。
如果 T 不是 LessThanComparable,則行為未定義。
2) 使用比較函式 comp 比較值。
3,4) 返回初始化列表 ilist 中的最小值和最大值。
如果 ilist.size() 為零,或者 T 不是 CopyConstructible,則行為未定義。
3) 使用 operator< 比較值。
如果 T 不是 LessThanComparable,則行為未定義。
4) 使用比較函式 comp 比較值。

目錄

[edit] 引數

a, b - 要比較的值
ilist - 包含要比較值的初始化列表
comp - 比較函式物件(即滿足 Compare 要求的物件),如果第一個引數“小於”第二個引數,則返回 true

比較函式的簽名應等效於以下內容

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

雖然簽名不需要包含 const&,但函式不能修改傳遞給它的物件,並且必須能夠接受 Type1Type2 型別(可能為 const)的所有值,無論 值類別 如何(因此,不允許使用 Type1&,也不允許使用 Type1,除非對於 Type1 移動等同於複製(C++11 起))。
型別 Type1Type2 必須能夠讓型別 T 的物件隱式轉換為它們兩者。

[edit] 返回值

1,2) 如果 a < ba 等同於 b,則返回 std::pair<const T&, const T&>(a, b) 的結果。如果 b < a,則返回 std::pair<const T&, const T&>(b, a) 的結果。
3,4) 一個 pair,其中第一個元素是 ilist 中的最小值,第二個元素是最大值。如果多個元素等同於最小值,則返回最左側的此類元素。如果多個元素等同於最大值,則返回最右側的此類元素。

[edit] 複雜度

1) 恰好一次使用 operator< 的比較。
2) 恰好一次比較函式 comp 的應用。
3,4) 給定 N 作為 ilist.size()
3) 最多
3N
2
次使用 operator< 的比較。
4) 最多
3N
2
次比較函式 comp 的應用。

[edit] 可能的實現

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);
}

[edit] 注意

對於過載 (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

[edit] 示例

#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

[edit] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 2239 C++11 對於過載 (2,4),曾要求 TLessThanComparable 未要求

[edit] 另請參閱

返回給定值中較小的那個
(函式模板) [編輯]
返回給定值中較大的那個
(函式模板) [編輯]
返回範圍中最小和最大的元素
(函式模板) [編輯]
返回兩個元素中較小和較大的一個
(演算法函式物件)[編輯]