C++ std::clamp

一、基本概念

std::clamp 是 C++17 在 <algorithm> 头文件中引入的一个函数模板。它的作用是将一个值限制在指定的范围内。

函数原型:

1
2
3
4
5
template< class T >
constexpr const T& clamp( const T& v, const T& lo, const T& hi );

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

参数:

  • v: 要限制的值
  • lo: 下限
  • hi: 上限
  • comp: 可选的比较函数对象

返回值:

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

其内部的实现类似于如下代码:

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

注意:

  • 必须保证 lo <= hi,否则行为未定义
  • std::clamp 返回的是引用,这意味着它不会创建新的对象
  • 对于自定义类型,需要确保正确重载了比较运算符

二、基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <algorithm>

int main() {
std::cout << std::clamp(10, 1, 100) << std::endl;
std::cout << std::clamp(0, 1, 100) << std::endl;
std::cout << std::clamp(1000, 1, 100) << std::endl;

double pi = 3.14159;
std::cout << std::clamp(pi, 3.0, 3.5) << std::endl;

return 0;
}

/*
output:
10
1
100
3.14159
*/

三、高级用法

3.1 自定义比较函数

std::clamp 允许我们传入自定义的比较函数,这在处理复杂对象时特别有用。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <algorithm>
#include <string>

int main() {
auto cmp = [](const std::string& a, const std::string& b) { return a.length() < b.length(); };

std::string result = std::clamp(std::string("hello"), std::string("a"), std::string("world"), cmp);
std::cout << result << std::endl; // 输出: hello

return 0;
}

3.2 与 lambda 表达式结合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <algorithm>
#include <vector>

int main() {
std::vector<int> numbers = {1, 5, 10, 15, 20};

std::for_each(numbers.begin(), numbers.end(), [](int& n) {
n = std::clamp(n, 5, 15);
});

for (int n : numbers) {
std::cout << n << " ";
}
// 输出: 5 5 10 15 15

return 0;
}

3.3 图形编程

在图形编程中,std::clamp 常用于限制颜色值或坐标。

1
2
3
4
5
6
7
8
9
struct Color {
int r, g, b;

void normalize() {
r = std::clamp(r, 0, 255);
g = std::clamp(g, 0, 255);
b = std::clamp(b, 0, 255);
}
};

3.4 信号处理,参数读写

在信号处理中,std::clamp 可用于限制信号的幅度。

在参数读写中,std::clamp 可用于保护参数的范围,避免异常数据的写入与读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::vector<double> processSignal(const std::vector<double>& signal, double minAmplitude, double maxAmplitude) {
std::vector<double> processedSignal;
for (double sample : signal) {
processedSignal.push_back(std::clamp(sample, minAmplitude, maxAmplitude));
}
return processedSignal;
}

template<typename T>
void writeParam(T data) {
if constexpr (std::is_unsigned<T>::value) {
data = std::clamp(v.toUInt(), r.first.toUInt(), r.second.toUInt());
} else if constexpr (std::is_floating_point<T>::value) {
data = std::clamp(v.toFloat(), r.first.toFloat(), r.second.toFloat());
} else {
data = std::clamp(v.toInt(), r.first.toInt(), r.second.toInt());
}
// 写入参数
}

C++ std::clamp
http://example.com/2026/07/15/C-std-clamp/
作者
Yu xin
发布于
2026年7月15日
许可协议