名前空間
変種
操作

std::clamp

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
clamp
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
ヘッダー <algorithm> で定義
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
(1) (C++17以降)
template< class T, class Compare >

constexpr const T& clamp( const T& v, const T& lo, const T& hi,

                          Compare comp );
(2) (C++17以降)

v の値が [lohi] の範囲内にある場合、v を返します。それ以外の場合は、最も近い境界を返します。

1) 値を比較するために、operator<(C++20まで)std::less{}(C++20以降) を使用します。
TLessThanComparable でない場合、動作は未定義です。[1]
2) 値を比較するために、比較関数 comp を使用します。

lohi より大きい場合、動作は未定義です。

  1. NaN を避ければ、T は浮動小数点型にすることができます。

目次

[編集] パラメータ

v - クランプする値
lo, hi - v をクランプする境界
comp - 比較関数オブジェクト(すなわち、Compareの要件を満たすオブジェクト)。最初の引数が2番目の引数より小さい場合にtrueを返す。

比較関数のシグネチャは、以下と同等でなければならない。

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

シグネチャにconst&は必須ではないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関係なく、Type1Type2のすべての型(おそらくconst)の値を受け入れられなければならない(したがって、Type1&は許可されない。また、Type1のムーブがコピーと同等でない限り、Type1も許可されない(C++11以降))。
Type1Type2は、型Tのオブジェクトが両方に暗黙的に変換できるものでなければなりません。

[編集] 戻り値

vlo より小さい場合は lo への参照、hiv より小さい場合は hi への参照、それ以外の場合は v への参照を返します。

[編集] 計算量

1) operator<(C++20まで)std::less{}(C++20以降) を使用して、最大2回の比較を行います。
2) 比較関数 comp を最大2回適用します。

[編集] 可能な実装

clamp (1)
template<class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
{
    return clamp(v, lo, hi, less{});
}
clamp (2)
template<class T, class Compare>
constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp)
{
    return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
}

[編集] 注釈

std::clamp の結果を参照で取得すると、いずれかのパラメータが一時オブジェクトであり、そのパラメータが返される場合に、ダングリング参照が発生します。
int n = -1;
const int& r = std::clamp(n, 0, 255); // r is dangling

v がいずれかの境界と比較して等しい場合、境界ではなく v への参照を返します。

機能テストマクロ 規格 機能
__cpp_lib_clamp 201603L (C++17) std::clamp

[編集]

#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>
 
int main()
{
    std::cout << "[raw] "
                 "[" << INT8_MIN << ',' << INT8_MAX << "] "
                 "[0," << UINT8_MAX << "]\n";
 
    for (const int v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
        std::cout << std::setw(4) << v
                  << std::setw(11) << std::clamp(v, INT8_MIN, INT8_MAX)
                  << std::setw(8) << std::clamp(v, 0, UINT8_MAX) << '\n';
}

出力

[raw] [-128,127] [0,255]
-129       -128       0
-128       -128       0
  -1         -1       0
   0          0       0
  42         42      42
 127        127     127
 128        127     128
 255        127     255
 256        127     255

[編集] 関連項目

与えられた値のうち小さい方を返す
(関数テンプレート) [編集]
与えられた値のうち大きい方を返す
(関数テンプレート) [編集]
(C++20)
整数値が指定された整数型の範囲内にあるかを確認する
(関数テンプレート) [編集]
値を一対の境界値の間に制限する
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)