代码之家  ›  专栏  ›  技术社区  ›  ABu

C++:使用fold表达式编译时“dominoe-update”

  •  1
  • ABu  · 技术社区  · 1 年前

    考虑以下代码:

    #include <iostream>
    #include <functional>
    
    template<class Val, class P>
    void dominoe_update(P, Val&) {}
    
    template<class Val, class Lval, class... More, class P>
    void dominoe_update(P p, Val&& val, Lval& lval, More&... more)
    {
        if (p(val, lval)) {
            lval = val; // No need to forward since it'd potentialy chain more copies anyway
            dominoe_update(p, val, more...);
        }
    }
    
    int main(int, char**)
    {
        int i = 8, j = 9, k = 1;
        dominoe_update(std::less{}, 2, i, j, k);
        std::cout << i << ' ' << j << ' ' << k << '\n'; // Prints 2 2 1
        return 0;
    }
    

    dominoe_update 使用更新所有参数 val 直到 p 退货 false .

    主要问题:是否可以使用fold表达式来实现上述函数,以删除递归并删除基本情况函数?我认为这是不可能的,因为短路逻辑。

    次要问题:是否可以将谓词写成最后一个自变量,而不是第一个自变量?我知道在变分论点之后写论点是“复杂的”,但我认为在某些情况下,推理规则允许这样做。

    第三个问题:你认为这个函数有更好的名字吗?我正在考虑为常见情况提供一些实用函数,如最小化和最大化,但是 dominoe_minimize dominoe_maximize 对我来说,不要像一般的名字那么好听。

    2 回复  |  直到 1 年前
        1
  •  1
  •   Ted Lyngmo    1 年前

    有一种方法:

    template <class P, class Val, class... Lvals>
    void dominoe_update(P p, Val&& val, Lvals&&... lval) {
        ((/*if*/        p(val, lval)
          /*then*/      && (lval = val, true))
          /*and next*/  && ...);
    }
    

    Demo

        2
  •  1
  •   Igor Tandetnik    1 年前

    接受挑战。

    template<typename P, typename Val, typename... Lval>
    void dominoe_update(P p, Val&& val, Lval&... lval)
    {
        bool go = true;
        ( (go && (go = p(val, lval)) ? (void(lval = val), 0) : 0), ...);
    }
    

    Demo