[C ++模板包,折叠两次

问题描述 投票:0回答:1

我已经阅读了一些相似的问题,但是找不到我想要的确切东西。

以纯粹的数学方式,将列表递归定义为:(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中,引入了折叠,所以可以做这样的事情:

template<typename...types>
auto sum(types...values) {
  return (... + values);
}

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

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

有人对如何连续获得两折有任何建议吗?

c++ templates variadic-templates fold
1个回答
1
投票

您可以一次解压缩参数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

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

© www.soinside.com 2019 - 2024. All rights reserved.