使用可变参数函数模板在C ++中折叠

模板参数包是在C ++ 11中引入的。 今天,我们将利用它来编写fold功能。 对于那些不知道fold(add, 1, 2, 3, 4, 5)表达式是什么折叠函数的人,我们将输出(1 +(2 + (3 + (4 + 5)))) = 15 (左折)。 类似地,对于fold(mul, 1, 2, 3, 4, 5) ,我们将输出120。有关更多信息,请参见此处

让我们从代码开始。

下面的小片段实际上是我们所有功能的折叠功能。

// Base Case - Return the only remaining element.
template < typename Func, typename T>
T fold (Func f, T v) {
    return v;
}

// General Case - Apply function to current element
// and folded output of the previous elements.
template < typename Func, typename T, typename ... Args>
T fold (Func f, T first, Args... args) {
    return f(first,fold(f, args...));
}

我们可以通过以下方式调用fold函数。

// Sample function for testing.
template < typename T>
T add (T x, T y)  { return x + y; }

int main () {
    fold(add< double >, 1 , 2 , 3 );
}

这里发生的是,当我们在main中调用fold时,一般情况由编译器选择,并推导参数的类型。 Func的类型为double (*)(double, double) ,而T为int ,标准所称的Args参数包为{ int , int } 。 我们实质上从包装中剥离了第一个参数,并用它调用二进制函数,并将折算结果应用于包装的其余部分。 如果您对递归感到满意,您将很容易理解正在发生的事情。 我们正在创建类似于以下所示的表达式树。

因此,对于每个递归函数,我们都需要一个基本案例作为结尾。 在这种情况下,当我们只剩下函数和单个参数时,我们将返回该参数。 这为我们提供了基本值,并允许我们的树折叠计算输出。

要直观地看到我们假定的类型实际上是由编译器推导的类型,请尝试下面的代码。

# include <iostream>

// Base Case - Return the only remaining element.
template < typename Func, typename T>
T fold (Func f, T v)
 {
    std :: cout << "Base Function :" << __PRETTY_FUNCTION__ << "\n" ;
    return v;
}

// General Case - Apply function to current element
// and folded output of the previous elements.
template < typename Func, typename T, typename ... Args>
T fold (Func f, T first, Args... args)
 {
    std :: cout << __PRETTY_FUNCTION__ << "\n" ;
    return f(first, fold(f, args...));
}

// Sample functions for testing.
template < typename T>
T add (T x, T y)  { return x + y; }

int main ()
 {
    fold(add< double >, 1 , 2 , 3 );
}

使用g ++编译器编译并执行此代码将为您提供帮助。

T fold(Func, T, Args ...) [with Func = double (*)(double, double); T = int; Args = {int, int}]
T fold(Func, T, Args ...) [with Func = double (*)(double, double); T = int; Args = {int}]
Base Function :T fold(Func, T) [with Func = double (*)(double, double); T = int]

这就是我们所期望的。 这是我们树的一种表示。

提示:在正确的位置使用constexpr关键字,如果我们知道编译时的参数,则可以使编译器轻松地在编译时计算值。

From: https://hackernoon.com/folding-in-c-using-variadic-function-template-4o3c3ya1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值