namespace std {
template <class T>
pair<const T&, const T&> minmax(const T& a, const T& b); // (1) C++11
template <class T>
constexpr pair<const T&, const T&> minmax(const T& a, const T& b); // (1) C++14
template <class T, class Compare>
pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp); // (2) C++11
template <class T, class Compare>
constexpr pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp); // (2) C++14
template <class T>
pair<T, T> minmax(initializer_list<T> t); // (3) C++11
template <class T>
constexpr pair<T, T> minmax(initializer_list<T> t); // (3) C++14
template <class T, class Compare>
pair<T, T> minmax(initializer_list<T> t, Compare comp); // (4) C++11
template <class T, class Compare>
constexpr pair<T, T> minmax(initializer_list<T> t, Compare comp); // (4) C++14
}
概要
同じ型の2つの値、もしくはinitializer_list
によるN個の値のうち、最小値と最大値の組を取得する。
最後の引数comp
は、2項の述語関数オブジェクトであり、これを使用して比較演算をカスタマイズすることができる。
要件
- 型
T
がoperator<
による比較が可能であること。 initializer_list
バージョンはそれに加えて、要素数が1以上であり、T
がコピーコンストラクト可能であること。
戻り値
first
が最小値、second
が最大値となるpair
オブジェクト
計算量
- 2値比較バージョンは1操作。
initializer_list
バージョンは高々(3/2) * t.size()
回の述語適用。
備考
- (1), (2) : 引数に右辺値を与えた場合、
minmax
の呼び出しを含む式の評価が終わった時点で、返された参照は寿命が切れている(ダングリング)ことに注意:
#include <cassert>
#include <algorithm>
int main()
{
int x = 10;
auto result1 = std::minmax(x, 11); // decltype(result1) == std::pair<const int&, const int&>
assert(result1.first == 10); // ok: result1.first は xを参照している
//assert(result1.second == 11); // 未定義動作 : result1.secondは寿命が尽きたオブジェクトを指しているため、
// そのオブジェクトにアクセスしてはならない
std::pair<int, int> result2 = std::minmax(x, 11);
assert(result2.first == 10); // ok: result2.first は xのコピーを持っている
assert(result2.second == 11); // ok: result2.second は 右辺値11のコピーを持っている
}
16
#include <cassert>
#include <algorithm>
int main()
{
int x = 10;
auto result1 = std::minmax(x, 11); // decltype(result1) == std::pair<const int&, const int&>
assert(result1.first == 10); // ok: result1.first は xを参照している
//assert(result1.second == 11); // 未定義動作 : result1.secondは寿命が尽きたオブジェクトを指しているため、
// そのオブジェクトにアクセスしてはならない
std::pair<int, int> result2 = std::minmax(x, 11);
assert(result2.first == 10); // ok: result2.first は xのコピーを持っている
assert(result2.second == 11); // ok: result2.second は 右辺値11のコピーを持っている
}
例
#include <cassert>
#include <algorithm>
#include <functional>
int main()
{
std::pair<int, int> result1 = std::minmax(2, 3);
assert(result1.first == 2 && result1.second == 3);
std::pair<int, int> result2 = std::minmax(2, 3, std::greater<int>());
assert(result2.first == 3 && result2.second == 2);
std::pair<int, int> result3 = std::minmax({1, 2, 3});
assert(result3.first == 1 && result3.second == 3);
std::pair<int, int> result4 = std::minmax({1, 2, 3}, std::greater<int>());
assert(result4.first == 3 && result4.second == 1);
}
19
#include <cassert>
#include <algorithm>
#include <functional>
int main()
{
std::pair<int, int> result1 = std::minmax(2, 3);
assert(result1.first == 2 && result1.second == 3);
std::pair<int, int> result2 = std::minmax(2, 3, std::greater<int>());
assert(result2.first == 3 && result2.second == 2);
std::pair<int, int> result3 = std::minmax({1, 2, 3});
assert(result3.first == 1 && result3.second == 3);
std::pair<int, int> result4 = std::minmax({1, 2, 3}, std::greater<int>());
assert(result4.first == 3 && result4.second == 1);
}
出力
実装例
template <class T>
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);
}
template <class T, class Compare>
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);
}
template <class T>
std::pair<T, T> minmax(std::initializer_list<T> init)
{
std::pair<const T*, const T*> p = std::minmax_element(init.begin(), init.end());
return std::make_pair(*p.first, *p.second);
}
template <class T, class Compare>
std::pair<T, T> minmax(std::initializer_list<T> init, Compare comp)
{
std::pair<const T*, const T*> p = std::minmax_element(init.begin(), init.end(), comp);
return std::make_pair(*p.first, *p.second);
}
バージョン
言語
- C++11
処理系
- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2013 ✅, 2015 ✅
参照
- N1840 C++0x Proposal: Function template
std::minmax
and / or algorithmstd::minmax_element
- N1990 Proposed Text for
minmax
(N1840) - N2551 A Variadic
std::min(T, ...)
for the C++ Standard Library - N2772 Variadic functions: Variadic templates or initializer lists? -- Revision 1
- LWG2350 - min, max, and minmax should be constexpr