std::minmax
From cppreference.com
| ヘッダー <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, |
(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, |
(4) | (C++11以降) (C++14以降constexpr) |
与えられた値の中で最小値と最大値を返します。
1,2) aとbの小さい方と大きい方への参照を返します。
1) operator< を使用して値を比較します。
もし
TがLessThanComparableでない場合、動作は未定義です。2) 比較関数 comp を使用して値を比較します。
3,4) 初期化子リスト ilist の値の最小値と最大値を返します。
3) operator< を使用して値を比較します。
もし
TがLessThanComparableでない場合、動作は未定義です。4) 比較関数 comp を使用して値を比較します。
目次 |
[編集] パラメータ
| a, b | - | 比較する値 |
| ilist | - | 比較する値を含む初期化子リスト |
| comp | - | 比較関数オブジェクト(すなわち、Compareの要件を満たすオブジェクト)。最初の引数が2番目の引数より小さい場合にtrueを返す。 比較関数のシグネチャは、以下と同等でなければならない。 bool cmp(const Type1& a, const Type2& b); シグネチャにconst&は必須ではないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関係なく、 |
[編集] 戻り値
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 の最小値を最初の要素とし、最大値を2番目の要素とするペアを返します。複数の要素が最小値と同値の場合、最も左の要素が返されます。複数の要素が最大値と同値の場合、最も右の要素が返されます。
[編集] 計算量
1) operator< を用いた厳密に1回の比較。
2) 比較関数 comp の厳密に1回の適用。
3,4) ilist.size() をNとする。
3) operator< を用いた比較は最大で
回。
| 3N |
| 2 |
4) 比較関数 comp の適用は最大で
回。
| 3N |
| 2 |
[編集] 実装例
| minmax (1) |
|---|
| minmax (2) |
| 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 | オーバーロード (2,4) の場合、TはLessThanComparableである必要がありました。 |
要求されない |
[編集] 関連項目
| 与えられた値のうち小さい方を返す (関数テンプレート) | |
| 与えられた値のうち大きい方を返す (関数テンプレート) | |
| (C++11) |
範囲内で最小の要素と最大の要素を返す (関数テンプレート) |
| (C++20) |
2つの要素の小さい方と大きい方を返す (アルゴリズム関数オブジェクト) |