std::ranges:: clamp
std::ranges
| Non-modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Partitioning operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sorting operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Binary search operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Heap operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Minimum/maximum operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Permutation operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fold operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Operations on uninitialized storage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Return types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
헤더에 정의됨
<algorithm>
|
||
|
함수 시그니처
|
||
|
template
<
class
T,
class
Proj
=
std::
identity
,
std::
indirect_strict_weak_order
<
std
::
projected
<
const
T
*
, Proj
>>
Comp
=
|
(C++20부터) | |
std::
invoke
(
proj, v
)
값이
[
std::
invoke
(
proj, lo
)
,
std::
invoke
(
proj, hi
)
]
범위 내에 있으면
v
를 반환하고, 그렇지 않으면 가장 가까운 경계값을 반환합니다.
std:: invoke ( proj, lo ) 가 std:: invoke ( proj, hi ) 보다 크면 동작이 정의되지 않습니다.
이 페이지에서 설명하는 함수형 개체들은 algorithm function objects (일반적으로 niebloids 로 알려진)입니다. 즉:
- 명시적 템플릿 인수 목록은 이들 중 어느 것을 호출할 때도 지정할 수 없습니다.
- 이들 중 어느 것도 인수 의존 이름 검색 에 보이지 않습니다.
- 이들 중 어느 것이 함수 호출 연산자의 왼쪽 이름으로 일반 비한정 이름 검색 에 의해 발견될 때, 인수 의존 이름 검색 이 억제됩니다.
목차 |
매개변수
| v | - | 제한할 값 |
| lo, hi | - | v 를 제한할 경계값 |
| comp | - | 투영된 요소들에 적용할 비교 연산 |
| proj | - | v , lo 및 hi 에 적용할 투영 연산 |
반환값
lo 의 투영 값이 v 의 투영 값보다 작으면 lo 에 대한 참조, hi 의 투영 값이 v 의 투영 값보다 작으면 hi 에 대한 참조, 그렇지 않으면 v 에 대한 참조.
복잡도
최대 두 번의 비교와 세 번의 투영 적용.
가능한 구현
struct clamp_fn { template<class T, class Proj = std::identity, std::indirect_strict_weak_order<std::projected<const T*, Proj>> Comp = std::ranges::less> constexpr const T& operator()(const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {}) const { auto&& pv = std::invoke(proj, v); if (std::invoke(comp, std::forward<decltype(pv)>(pv), std::invoke(proj, lo))) return lo; if (std::invoke(comp, std::invoke(proj, hi), std::forward<decltype(pv)>(pv))) return hi; return v; } }; inline constexpr clamp_fn clamp; |
참고 사항
std::ranges::clamp
by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned:
int n = -1; const int& r = std::ranges::clamp(n, 0, 255); // r은 댕글링 참조입니다
만약 v 가 어느 한 경계와 동등하게 비교되면, 경계가 아닌 v 에 대한 참조를 반환합니다.
프로젝션이 값을 반환하고 비교자가 값을 인수로 받는 경우, 프로젝션 결과 타입에서 비교자 매개변수 타입으로의 이동(move)이 복사(copy)와 동등하지 않다면 이 함수를 사용해서는 안 됩니다.
std::invoke
를 통한 비교가 프로젝션의 결과를 변경할 경우,
std::regular_invocable
의 의미론적 요구사항(이는
std::indirect_strict_weak_order
에 포함됨)으로 인해 동작이 정의되지 않습니다.
표준은 투영(projection) 결과의 값 범주(value category)가 보존되어야 하며, proj 는 v 에 대해 한 번만 호출될 수 있습니다. 이는 prvalue인 투영 결과가 비교자(comparator)에 대한 두 번의 호출을 위해 캐시되고 두 번 이동되어야 함을 의미합니다.
- libstdc++ 는 이를 준수하지 않으며 항상 projection 결과를 lvalue로 전달합니다.
- libc++ 는 projection을 두 번 실행했으나, Clang 18에서 수정되었습니다.
- MSVC STL 는 projection을 두 번 실행했으나, VS 2022 17.2에서 수정되었습니다.
예제
#include <algorithm> #include <cstdint> #include <iomanip> #include <iostream> #include <string> using namespace std::literals; namespace ranges = std::ranges; int main() { std::cout << "[raw] [" << INT8_MIN << ',' << INT8_MAX << "] " "[0" << ',' << UINT8_MAX << "]\n"; for (int const v : {-129, -128, -1, 0, 42, 127, 128, 255, 256}) std::cout << std::setw(4) << v << std::setw(11) << ranges::clamp(v, INT8_MIN, INT8_MAX) << std::setw(8) << ranges::clamp(v, 0, UINT8_MAX) << '\n'; std::cout << std::string(23, '-') << '\n'; // 투영 함수 const auto stoi = [](std::string s) { return std::stoi(s); }; // 위와 동일하지만 문자열 사용 for (std::string const v : {"-129", "-128", "-1", "0", "42", "127", "128", "255", "256"}) std::cout << std::setw(4) << v << std::setw(11) << ranges::clamp(v, "-128"s, "127"s, {}, stoi) << std::setw(8) << ranges::clamp(v, "0"s, "255"s, {}, stoi) << '\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 ----------------------- -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)
|
주어진 값들 중 더 작은 값을 반환합니다
(알고리즘 함수 객체) |
|
(C++20)
|
주어진 값들 중 더 큰 값을 반환합니다
(알고리즘 함수 객체) |
|
(C++20)
|
정수 값이 주어진 정수 타입의 범위 내에 있는지 확인합니다
(함수 템플릿) |
|
(C++17)
|
값을 한 쌍의 경계값 사이로 고정합니다
(함수 템플릿) |