跳到主要内容

std::clamp() 算法

// (1)
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );

// (2)
template< class T, class Compare >
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );
  • 如果 v 小于 lo,则返回 lo

  • 否则,如果 v 大于 hi,则返回 hi

  • 否则返回 v

  • (1) 使用 operator< 比较值。

  • (2)(1),但使用 comp 比较值。

未定义行为

行为未定义

如果 lo 的值大于 hi

参数

v

要限制的值。

lo
hi

限制 v 的边界。

comp

比较函数对象(即满足 Compare 要求的对象),如果第一个参数小于第二个参数,则返回 true

bool cmp(const Type1 &a, const Type2 &b);
  • 签名不需要有 `const&`,但不得修改参数。
  • 必须接受类型(可能为 const)TypeType2 的所有值,无论值类别如何(因此不允许使用 Type1&除非对于 Type1,移动等同于复制,否则也不允许使用 Type1 (自 C++11 起)
  • Type1Type2 的类型必须使得 T 类型的对象可以隐式转换为它们两者。

类型要求

返回值

如果 v 小于 lo,则引用 lo;如果 hi 小于 v,则引用 hi;否则引用 v

复杂度

最多两次比较。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行时抛出异常且 ExecutionPolicy标准策略之一,则调用 std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

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 的引用,而不是边界。

示例

Main.cpp
#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>

int main()
{
std::cout << " raw clamped to int8_t clamped to uint8_t\n";
for (const int v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
{
std::cout
<< std::setw(04) << v
<< std::setw(20) << std::clamp(v, INT8_MIN, INT8_MAX)
<< std::setw(21) << std::clamp(v, 0, UINT8_MAX) << '\n';
}
}
输出
 raw   clamped to int8_t   clamped to uint8_t
-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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::clamp() 算法

// (1)
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );

// (2)
template< class T, class Compare >
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );
  • 如果 v 小于 lo,则返回 lo

  • 否则,如果 v 大于 hi,则返回 hi

  • 否则返回 v

  • (1) 使用 operator< 比较值。

  • (2)(1),但使用 comp 比较值。

未定义行为

行为未定义

如果 lo 的值大于 hi

参数

v

要限制的值。

lo
hi

限制 v 的边界。

comp

比较函数对象(即满足 Compare 要求的对象),如果第一个参数小于第二个参数,则返回 true

bool cmp(const Type1 &a, const Type2 &b);
  • 签名不需要有 `const&`,但不得修改参数。
  • 必须接受类型(可能为 const)TypeType2 的所有值,无论值类别如何(因此不允许使用 Type1&除非对于 Type1,移动等同于复制,否则也不允许使用 Type1 (自 C++11 起)
  • Type1Type2 的类型必须使得 T 类型的对象可以隐式转换为它们两者。

类型要求

返回值

如果 v 小于 lo,则引用 lo;如果 hi 小于 v,则引用 hi;否则引用 v

复杂度

最多两次比较。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行时抛出异常且 ExecutionPolicy标准策略之一,则调用 std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

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 的引用,而不是边界。

示例

Main.cpp
#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <iostream>

int main()
{
std::cout << " raw clamped to int8_t clamped to uint8_t\n";
for (const int v : {-129, -128, -1, 0, 42, 127, 128, 255, 256})
{
std::cout
<< std::setw(04) << v
<< std::setw(20) << std::clamp(v, INT8_MIN, INT8_MAX)
<< std::setw(21) << std::clamp(v, 0, UINT8_MAX) << '\n';
}
}
输出
 raw   clamped to int8_t   clamped to uint8_t
-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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。