• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

C++ 11:lambda,currying

c/c++ 来源:Cfon 4次浏览

我有以下代码。你能向我解释它是如何工作的吗?C++ 11:lambda,currying

template<typename Function, typename... Arguments> 
auto curry(Function func, Arguments... args) { 
    return [=](auto... rest) { 
     return func(args..., rest...); 
    }; 
} 

int main() { 
    auto add = [](auto x, auto y) { 
     return x + y; 
    }; 
    auto add4 = curry(add, 4); 
    std::cout << add4(3) << '\n'; //output: 7. (Ok) 

} 


===========解决方案如下:

首先,你要知道什么是currying,或者在你的问题,这是专门的partial application的情况下(到钻营是相关的,但略有不同)。

基本上,这意味着减少的功能有一定数目的参数来创建另一个功能与一些固定参数的值。

我你所示例的,原始的功能是add(x,y)它有两个参数Xÿ。你减少函数的元数通过设置X至4添加和创建减小的函数add4(y)

ADD4(Y)=添加(X,Y)其中X = 4

现在,你的C++代码如何实现?借助可变模板,可变参数函数拉姆函数

Lambda functions从C++ 11开始就是C++。实质上,它们是动态创建的匿名函数,可以存储在变量中。您在main()创建add作为拉姆达:

auto add = [](auto x, auto y) { 
return x + y; 
}; 

一个由图案识别拉姆达[] (list-of-arguments) {function-body};

注:[]并非总是空的,请参阅“捕捉变量” there,我们会回来它后来。

现在咖喱功能的目的是为了充分利用这些lambda表达式功能func和一定数目的值作为参数之一,并且通过定义新功能分配的值,以便,向func第一参数。

的“一定数目的参数”机构由variadic template参数Arguments... args其允许调用任何数量的类型的作为模板参数模板允许的(只要它们被称为编译时间)。所以在我们的例子中,传递的参数是4,因此Arguments... args将被替换为int,并且curry的实例将接受作为参数的lambda和int

如果我们看一下curry的代码,我们可以看到,它仅仅是一个lambda函数本身(这是一个variadic function,就像printf()),其唯一目的是连接它的值实例化时,已经是固定的参数模板(args...)以及那些将其值作为参数传递给curried函数的模板(rest...)。

的[=]符号为lambda函数特殊捕获,其允许使用所有的局部变量的函数体(在这里它允许使用args)。

所以把它包起来,这里是你的主要功能是什么发生了:

  1. 您创建一个名为add变量,它包含了拉姆达 功能,取两个参数和添加。
  2. 当您致电curry(add,4)时,您将实例化curry模板。
    • 第一个模板参数Functionadd(拉姆达接受两个int并返回int
    • 第二可变参数的参数类型仅包含一种类型的:的4类型,即int

实例化的curry功能看起来像这样

curry((int,int)->(int) func, int arg){ 
    return [=](auto... rest) {return func(arg, rest...);}; 
} 

请注意,由于auto和模板类型扣除,您从不会看到这些类型。

  • 您然后调用该实例与func = addarg = 4

  • 您存储此实例中add4现在是一个拉姆达采取一个参数的结果。然后,您可以有3个呼叫add4作为参数(rest...为3),然后将调用add(4,3)并返回7.

  • 注意,在技术上你可以尝试调用add4一个以上的说法,因为咖喱功能是一个可变参数函数。编译器只会在调用add(请参阅here)


    版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
    喜欢 (0)