You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用折叠表达式实现短路式多米诺(级联)更新函数?

多米诺更新:用折叠表达式替代递归实现短路逻辑

我正在编写一个可变模板函数以实现「多米诺更新」:给定断言p,遍历多个左值(按引用传递)并将val赋值给它们,直到p(val, lval)返回false时停止。

我的当前递归实现如下:

#include <iostream>
#include <functional>

template<class Val, class P>
void domino_update(P, Val&) {}

template<class Val, class Lval, class... More, class P>
void domino_update(P p, Val&& val, Lval& lval, More&... more)
{
    if (p(val, lval)) {
        lval = val; // No need to forward since it'd potentially chain more copies anyway
        domino_update(p, val, more...);
    }
}

int main(int, char**)
{
    int i = 8, j = 9, k = 1;
    domino_update(std::less{}, 2, i, j, k);
    std::cout << i << ' ' << j << ' ' << k << '\n'; // Prints 2 2 1
    return 0;
}

但我不喜欢递归实现,想改用折叠表达式避免递归(无需实现模板基例),同时保留短路逻辑(即p返回false后不再执行后续操作),该怎么做?


解决方案:利用折叠表达式的短路特性

可以借助C++17的折叠表达式结合辅助lambda,利用逻辑与&&的短路求值特性实现需求。核心思路是用&&连接每个左值的处理逻辑,一旦某个逻辑返回false,后续操作会被直接跳过。

实现代码如下:

#include <iostream>
#include <functional>

template<class P, class Val, class... Lvals>
void domino_update(P p, Val val, Lvals&... lvals)
{
    [[maybe_unused]] bool dummy = (
        [&](auto& lval) -> bool {
            if (p(val, lval)) {
                lval = val;
                return true;
            }
            return false;
        }(lvals) && ...
    );
}

int main(int, char**)
{
    int i = 8, j = 9, k = 1;
    domino_update(std::less{}, 2, i, j, k);
    std::cout << i << ' ' << j << ' ' << k << '\n'; // 输出 2 2 1
    return 0;
}

代码细节说明

  1. 折叠表达式的短路性:(lambda(lvals) && ...) 是一元右折叠,会依次将每个lvals传入lambda执行,并用&&连接结果。由于&&的短路特性,只要其中一个lambda返回false,后续的lambda调用就会被终止。
  2. 辅助lambda的作用:lambda捕获外部的p和val,对每个左值先执行断言判断:
    • 断言为true时,完成赋值并返回true,继续处理下一个左值;
    • 断言为false时直接返回false,触发短路逻辑,停止后续所有操作。
  3. 无需基例模板:当可变参数为空时,逻辑与的空折叠结果为true,函数不会执行任何实际操作,因此不需要额外编写空参数的基例模板。
  4. dummy变量:用[[maybe_unused]]标记变量来接收折叠表达式的结果,避免编译器因表达式无实际用途而发出警告。

这个实现完全替代了递归逻辑,同时完整保留了原有的短路更新行为。

内容的提问来源于stack exchange,提问作者ABu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:07:40