C++如何将可变数量lambda组合的pipe函数改写为lambda?
C++23 最优实现方案
C++23 引入的**显式对象参数(deduction this)**特性可以直接解决lambda无法递归调用自身的问题,不需要额外工具,代码逻辑和你原有模板实现几乎完全一致,pipe本身就是纯lambda:
#include <iostream> #include <string> #include <utility> template <typename F, typename G> auto compose(F f, G g) { return [f, g](auto&&... xs) { return g(f(std::forward<decltype(xs)>(xs)...)); }; } int main() { // pipe为纯lambda实现 auto pipe = []<typename Self, typename F, typename G, typename... Fs>(this const Self& self, F f, G g, Fs... fs) { if constexpr (sizeof...(fs) > 0) { auto fg = compose(f, g); return self(fg, fs...); } else { return compose(f, g); } }; // 测试逻辑和原代码完全一致 auto add_x = [](const auto& x) { return [x](auto y) { std::cout << "+" << x << std::endl; return y + x; }; }; auto to_str = [](const auto& s) { std::cout << "to_str" << std::endl; return std::string("String:") + std::to_string(s); }; auto add_1 = add_x(1); auto add_2 = add_x(2); auto add_3 = add_x(3); auto piped = pipe(add_1, add_2, add_3, to_str); auto x = piped(3); std::cout << x << std::endl; }
运行结果和原有模板实现完全相同:
+1 +2 +3 to_str String:9
C++17 兼容实现方案
如果使用C++17及更早版本,可以用函数式编程经典的**Y组合子(固定点组合子)**实现递归lambda,不需要依赖高版本特性:
#include <iostream> #include <string> #include <utility> template <typename F, typename G> auto compose(F f, G g) { return [f, g](auto&&... xs) { return g(f(std::forward<decltype(xs)>(xs)...)); }; } // 通用Y组合子实现 template <typename F> struct y_combinator { F f; template <typename... Args> decltype(auto) operator()(Args&&... args) const { return f(*this, std::forward<Args>(args)...); } }; template <typename F> y_combinator(F) -> y_combinator<F>; int main() { // 用Y组合子包装的递归lambda版pipe auto pipe = y_combinator{ [](auto&& self, auto f, auto g, auto... fs) { if constexpr (sizeof...(fs) > 0) { auto fg = compose(f, g); return self(fg, fs...); } else { return compose(f, g); } } }; // 测试逻辑和上面完全一致,运行结果相同 }
内容的提问来源于stack exchange,提问作者stuckprogrammersad
相关产品推荐
相关产品推荐

