c++ 元编程 lambda
时间: 2025-01-06 21:47:11 浏览: 6
### C++ 中元编程与 Lambda 表达式的结合
Lambda 表达式在现代 C++ 编程中扮演着重要角色,尤其是在模板元编程 (TMP) 的上下文中。通过将 lambda 和 TMP 结合起来,可以实现更简洁、高效的编译期计算。
#### 使用 `constexpr` 函数和 Lambda 实现编译期计算
自 C++14 起,lambda 可以被标记为 `constexpr`,这意味着它们可以在编译期间执行。这使得编写复杂的编译期逻辑变得更加容易[^1]:
```cpp
#include <iostream>
// 定义一个 constexpr lambda 来计算阶乘
auto factorial = [](int n) -> int {
return n <= 1 ? 1 : n * factorial(n - 1);
};
static_assert(factorial(5) == 120, "Factorial of 5 should be 120");
int main() {
std::cout << "Factorial of 7 is: " << factorial(7) << '\n';
}
```
此代码展示了如何利用 `constexpr` lambda 进行简单的数学运算,并验证其正确性。
#### 将 Lambda 作为模板参数传递
另一个强大的特性是可以把捕获为空的 lambda 当作非类型模板参数来使用。这种方法允许创建高度定制化的函数对象,在编译时就已完全展开并优化:
```cpp
template<typename T>
struct apply_lambda {};
template<auto F>
struct apply_lambda<F> {
template<typename... Args>
static auto invoke(Args&&... args){
return F(std::forward<Args>(args)...);
}
};
void example(){
// 创建一个立即调用形式的 lambda 并将其作为模板实参传入
using my_func_t = apply_lambda<
[](){return 42;}
>;
std::cout << "Result from templated lambda call:"
<< my_func_t::invoke() << "\n";
}
```
这段程序说明了怎样定义通用结构体并通过特定实例化方式应用不同的行为模式。
#### 利用 SFINAE 技术增强灵活性
SFINAE(Substitution Failure Is Not An Error)是一种用于条件重载的技术。当与 lambda 配合工作时,可以根据输入类型的属性自动选择最合适的版本:
```cpp
#include <type_traits>
// 基础版:只接受整数型数据
auto add_ints_if_possible_impl(int a, int b){
return a+b;
}
// 版本二:如果两个操作数都是浮点数,则返回 double 类型的结果;否则失败
template<class A,class B,
class=std::enable_if_t<std::is_floating_point_v<A>&&std::is_floating_point_v<B>>>
auto add_floats_if_possible(A a,B b)->double{
return a+b;
}
// 组合成单个接口
auto add_numbers = [](auto&& lhs, auto&& rhs){
if constexpr(
requires{add_floats_if_possible(lhs,rhs);} // 如果能匹配到 float 加法...
){
return add_floats_if_possible(lhs,rhs); // ...则优先采用之
}else{
return add_ints_if_possible_impl(lhs,rhs); // 否则退而求其次选整数加法
}
};
```
上述例子中展示了一个灵活处理不同类型数值相加的方法,它会依据实际提供的参数决定具体采取哪种策略来进行累加操作。
阅读全文