最終更新日時(UTC):
が更新

履歴 編集

function template
<algorithm>

std::minmax(C++11)

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項の述語関数オブジェクトであり、これを使用して比較演算をカスタマイズすることができる。

要件

  • Toperator<による比較が可能であること。
  • 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のコピーを持っている
}

#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

処理系

参照