std::minmax

從 cppreference.com
< cpp‎ | algorithm
 
 
算法庫
受約束算法及範圍上的算法 (C++20)
包含算法例如 ranges::copy, ranges::sort, ...
執行策略 (C++17)
排序和相關操作
劃分操作
排序操作
二分搜索操作(在已劃分範圍上)
集合操作(在有序範圍上)
歸併操作(在有序範圍上)
堆操作
最小/最大操作
minmax
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫

數值運算
(C++11)                       
在未初始化內存上的操作
 
在標頭 <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 來比較這些值。

目錄

[編輯] 參數

a, b - 要比較的值
ilist - 擁有要比較的值的初始化器列表
cmp - 比較函數對象(即滿足比較 (Compare) 要求的對象),如果a 小於 b,則返回 ​true

比較函數的簽名應等價於如下:

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

雖然簽名不必有 const&,函數也不能修改傳遞給它的對象,而且必須能夠接受(可有 const 限定的)類型 Type1Type2 的所有值,與值類別無關(從而不允許 Type1 &,也不允許 Type1,除非 Type1 的移動等價於複製(C++11 起))。
類型 Type1Type2 必須使得 T 類型的對象能隱式轉換到這兩個類型。 ​

[編輯] 返回值

1,2) 如果 a < b 或者 a 等價於 b,那麼返回 std::pair<const T&, const T&>(a, b) 的結果。如果 b < a,那麼返回 std::pair<const T&, const T&>(b, a) 的結果。
3,4)ilist 中最小元素為第一元素,最大元素為第二元素的 pair。如果有多個等價於最小者的值,那麼返回最左側的這種值。如果有多個等價於最大者的值,那麼返回最右側的這種值。

[編輯] 複雜度

1) 應用一次 operator< 進行比較。
2) 應用一次比較函數 comp
3,4) 給定 Nilist.size()
3) 最多應用
3N
2
operator< 進行比較。
4) 最多應用
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; // 未定义行为
 
// 注意结构化绑定有同样的问题
auto [mm, xx] = std::minmax(n, n + 1);
xx; // 未定义行为

[編輯] 示例

#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++ 標準。

缺陷報告 應用於 出版時的行為 正確行為
LWG 2239 C++11 重載 (2,4)T 需要可小於比較 (LessThanComparable) 不需要

[編輯] 參閱

返回給定值中較小者
(函數模板) [編輯]
返回給定值中較大者
(函數模板) [編輯]
返回範圍中的最小元和最大元
(函數模板) [編輯]
返回兩個元素間的較小者和較大者
(算法函數對象) [編輯]