C++ 11:lambda,currying
我有以下代码。你能向我解释它是如何工作的吗?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
)。
所以把它包起来,这里是你的主要功能是什么发生了:
- 您创建一个名为
add
变量,它包含了拉姆达 功能,取两个参数和添加。 - 当您致电
curry(add,4)
时,您将实例化curry
模板。- 第一个模板参数
Function
是add
(拉姆达接受两个int
并返回int
) - 第二可变参数的参数类型仅包含一种类型的:的
4
类型,即int
- 第一个模板参数
实例化的curry
功能看起来像这样
curry((int,int)->(int) func, int arg){ return [=](auto... rest) {return func(arg, rest...);};
}
请注意,由于auto
和模板类型扣除,您从不会看到这些类型。
您然后调用该实例与
func
=add
和arg
= 4您存储此实例中
add4
现在是一个拉姆达采取一个参数的结果。然后,您可以有3个呼叫add4
作为参数(rest...
为3),然后将调用add(4,3)
并返回7.
注意,在技术上你可以尝试调用add4
一个以上的说法,因为咖喱功能是一个可变参数函数。编译器只会在调用add
(请参阅here)
以上是 C++ 11:lambda,currying 的全部内容, 来源链接: utcz.com/qa/262567.html