Namespaces
Variants

std::clamp

cppreference.net에서
 
 
알고리즘 라이브러리
제약된 알고리즘 및 범위에 대한 알고리즘 (C++20)
제약된 알고리즘, 예: ranges::copy, ranges::sort, ...
정렬 및 관련 연산
분할 연산
(C++11)    

정렬 연산
이진 탐색 연산
(분할된 범위에 대해)
집합 연산 (정렬된 범위에 대해)
병합 연산 (정렬된 범위에 대해)
힙 연산
최소/최대 연산
(C++11)
(C++17)
사전식 비교 연산
순열 연산


 
헤더 <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의 값이 [lo, hi] 범위 내에 있으면, v를 반환하고; 그렇지 않으면 가장 가까운 경계값을 반환합니다.

1) 값을 비교하기 위해 operator<(C++20까지)std::less{}(C++20부터)를 사용합니다.
T가 LessThanComparable이 아니면, 동작은 정의되지 않습니다.[1]
2) 비교 함수 comp를 사용하여 값을 비교합니다.

lo가 hi보다 크면, 동작은 정의되지 않습니다.

  1. ↑ 만약 NaN을 피하면, T는 부동소수점 타입이 될 수 있습니다.

매개변수

v - 클램프할 값
lo, hi - v를 클램프할 경계값
comp - 비교 함수 객체 (즉, Compare의 요구 사항을 만족하는 객체)로, 첫 번째 인수가 두 번째 인수보다 true작으면 를 반환합니다.

비교 함수의 시그니처는 다음과 동등해야 합니다:

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

시그니처에 const&가 필요하지는 않지만, 함수는 전달된 객체를 수정해서는 안 되며, Type1와 Type2 타입의 모든 값(상수 가능)을 값 범주에 관계없이 받아들일 수 있어야 합니다 (따라서 Type1&는 허용되지 않으며, 이동이 복사와 동등하지 않은 한 Type1도 허용되지 않습니다Type1(C++11부터) 이동이 복사와 동등한 경우는 제외).)
Type1와 Type2 타입은 T 타입의 객체가 두 타입 모두로 암시적으로 변환될 수 있어야 합니다.

반환값

lo가 v보다 작으면 lo에 대한 참조, hi가 hi보다 작으면 v에 대한 참조, 그렇지 않으면 v에 대한 참조.

복잡도

1) 최대 두 번의 비교 (operator<(C++20까지)std::less{}(C++20부터) 사용).
2) 최대 두 번의 비교 함수 comp 적용.

가능한 구현

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)
정수 값이 주어진 정수 타입의 범위 내에 있는지 확인합니다
(함수 템플릿)
값을 경계값 쌍 사이로 클램프합니다
(알고리즘 함수 객체)