我正在编写一个可变参数模板函数,它应该实现“多米诺骨牌”更新。也就是说:给定一个谓词
p
,它应该迭代多个 lval
(通过引用传递)并将 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;
}
但是,我不喜欢它是递归的。
我可以使用fold表达式来避免使用递归(并避免需要为模板实现基本情况),同时保持短路逻辑(即,
p
一旦返回就不应再次调用) false
)?怎么办?
这是一种方法:
template <class P, class Val, class... Lvals>
void domino_update(P p, Val&& val, Lvals&&... lval) {
((/*if*/ p(val, lval)
/*then*/ && (lval = val, true))
/*and next*/ && ...);
}
接受挑战。
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), ...);
}