最終更新日時: 2026年07月22日 16時08分23秒 (JST)
rotarymars が更新

履歴 編集

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

## 要件

- 型`T`が`operator<`による比較が可能であること。
- `initializer_list`バージョンはそれに加えて、要素数が1以上であり、`T`がコピーコンストラクト可能であること。

## 戻り値

`first`が最小値、`second`が最大値となる`pair`オブジェクト

## 計算量

- 2値比較バージョンは1操作。
- `initializer_list`バージョンは高々`(3/2) * t.size()`回の述語適用。

## 備考

- (1), (2) : 引数に一時オブジェクトを与えた場合、`minmax`の呼び出しを含む完全式の評価が終わる時点で、返された参照の寿命が切れる(ダングリング)ことに注意：

    #include <cassert>
    #include <algorithm>
    #include <utility>

    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>
    #include <utility>

    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 ✅

## 関連項目

- `ranges::minmax`

## 参照

- N1840 C++0x Proposal: Function template `std::minmax` and / or algorithm `std::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