C++ 17 constexpr lambda表达式

C++ 17 constexpr lambda表达式
枫C++ 17 constexpr lambda表达式
从 C++17 开始,
lambda表达式可以在满足条件时被当作constexpr使用。这个特性让 lambda 不再只是运行期的小函数对象,在一些场景下它也能参与编译期计算。
1. 什么是 constexpr lambda?
简单理解就是:如果一个 lambda 的函数体本身满足常量表达式要求,那么它就可以在编译期求值。
例如:
1 | constexpr auto add = [](int a, int b) { |
这里的 add(1, 2) 就可以在编译期直接算出结果。
2. C++17 之前和之后的区别
在早期标准里,lambda 更多是运行时工具,虽然能写得很灵活,但不太适合做编译期运算。
到了 C++17,这方面明显宽松了不少,很多简单 lambda 都能自然地变成常量表达式。
这对模板元编程、编译期辅助计算、以及一些需要 constexpr 回调的小场景都比较有帮助。
3. 基本示例
3.1 最简单的编译期计算
1 |
|
输出:
1 | 25 |
3.2 作为辅助判断函数
1 | constexpr auto isEven = [](int n) { |
这里 static_assert 能通过,就说明这个 lambda 已经参与了编译期判断。
4. 使用场景
4.1 编译期辅助函数
有些逻辑写成普通 constexpr 函数也可以,但写成 lambda 更适合局部使用:
1 | int main() |
这种写法适合“只在当前作用域内用一次”的编译期小工具。
4.2 配合 static_assert
1 | constexpr auto inRange = [](int x) { |
4.3 模板中的局部逻辑
在模板函数里,lambda 有时比再额外写一个帮助函数更顺手。
5. 使用时的限制
虽然 constexpr lambda 很方便,但并不是所有 lambda 都能参与编译期计算。
5.1 不能做运行期才能确定的事情
例如:
- 访问运行时输入
- 动态分配资源
- 调用非
constexpr函数
这些都不适合放进编译期求值逻辑里。
5.2 捕获内容也要注意
如果你捕获的是一个运行期变量,那 lambda 即使写成 constexpr 形式,也未必能在编译期真正求值。
例如:
1 | int x = 10; |
这里 x 是运行期变量,所以 func() 显然不是编译期常量表达式。
5.3 不是写了 constexpr 就一定编译期执行
这点和普通 constexpr 函数一样。
它的含义是“可以在编译期求值”,但实际是不是编译期执行,要看上下文是否要求常量表达式。
6. 和普通 constexpr 函数怎么选?
更适合用 constexpr 函数的情况
- 逻辑需要复用很多次
- 想要独立函数名
- 接口需要更明确
更适合用 constexpr lambda 的情况
- 只在局部作用域里用
- 逻辑很小
- 不想额外定义一个命名函数
7. 一个稍完整的例子
1 |
|
总结
constexpr lambda 让 lambda 的用途从“运行期简化代码”进一步扩展到了“编译期辅助计算”。
它很适合写一些局部、短小、一次性的编译期逻辑。对于现代 C++ 来说,这算是一个不算大但很实用的增强点。














