我读过一些相似的问题,但找不到确切的问题。

用纯粹的数学方法,将列表递归定义为:(head, rest)

其中head是列表中的第一个元素,而rest是列表。
因此,例如(1,2,3,4)表示为(1,(2,(3,(4,[]))))),其中[]是空列表。

然后,如果我们要遍历列表,我们可以像下面这样写一个递归函数:

iterate(list)
    head = list.head
    // do stuff and return if head is the empty element
    iterate(list.rest)

如果我们想遍历每两个元素,我们要做:
pair_iterate(list)
        head1 = list.head
        head2 = list.rest.head
        // do stuff and return if head is the empty element
        iterate(list.rest.rest)

我试图在C++中获得第二种行为。

在C++ 17中,引入了folds,因此可以执行以下操作:
template<typename...types>
auto sum(types...values) {
  return (... + values);
}

但是假设我们想要相邻参数的乘积之和,例如sum(1,2,3,4)1*2 + 3*4

在这种情况下,我们需要“折叠两次”来获得2个头来执行操作并传递其余列表。类似于我的伪代码。

有没有人建议如何连续获得2折?

编辑:
我特别想用折叠来做到这一点,即在函数声明内无需依赖递归模板化函数。

最佳答案

您可以一次解压缩参数2,如下所示:

template <typename T1, typename T2, typename ...Ts>
auto sum_products(T1 t1, T2 t2, Ts ...ts)
{
  return t1 * t2 + sum_products(ts...);
}

并提供无参数的基本情况重载:
auto sum_products() { return 0; }

然后像这样使用它:
std::cout << sum_products(1,2,3,4);  // prints 14

这是demo

请注意,这仅适用于偶数个参数,但是您可以轻松地添加单个参数重载来处理这种情况。

关于c++ - C++模板包,折叠两次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62380006/

10-15 16:47