我已经知道如何制作一个带有一个参数的递归lambda函数,例如计算数字的阶乘,但是我尝试使用lambda来创建递归幂函数(作为一种实践),但是在函数中使用2个参数会导致错误
此代码:
std::function <int(int)> power = [&](int a, int n)
{
return (n<=1) ? a : a*power(a, n-1);
};
此行return (n<=1) ? a : a*power(a, n-1);
出现以下错误:
error: no match for call to '(std::function<int(int)>) (int&, int)' note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes = {int}] note: candidate expects 1 argument, 2 provided
答案 0 :(得分:4)
也许
std::function <int(int, int)> power = [&](int a, int n) ....
// ...................^^^^^
?
我的意思是:如果power
是一个{lambda初始化的std::function
,该lambda接收两个整数,并且用作接收两个整数的函数,则声明它接收两个整数,而不仅仅是一个整数的情况。
答案 1 :(得分:4)
您必须使用
std::function <int(int, int)> power = [&](int a, int n) { ... }
该函数使用两个参数。
n = 0
。使用
return (n <= 1) ? a : a*power(a, n-1);
不正确。用a
调用函数时,您将返回n = 0
。
使用
return (n == 0) ? 1 : a*power(a, n-1);
unsigned int
用于n
。std::function <int(int, unsigned int)> power = [&](int a, unsigned int n) { ... }
然后,您不必担心会为n
用负值调用该函数。
std::function <int(int, unsigned int)> power = [&](int a, unsigned int n)
{
return (n == 0) ? 1 : a*power(a, n-1);
};
答案 2 :(得分:0)
您的递归lambda遇到了问题;它需要创建时所使用的确切变量,否则必须称为UB。
auto ycomb = [](auto&&f){ return [f=f](auto&&...args){ return f(f, decltype(args)(args)...); }; };
这个小玩具修复了这个错误。
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(self, a, n-1);
});
有。
ycomb
是ycombinator。很有名。
此power
可以被复制,并且可以安全地超过其构造范围。
如果您不喜欢self(self, args...)
,则可以重复使用ycombinator来制作它:
auto ycomb0 = [](auto&&f){
return [=](auto&&...args){
return f(f, decltype(args)(args)...);
};
};
auto ycombx_ref = [](auto&& r, auto&& f) {
return [&r, f](auto&&...args) {
return f( r(r, f), decltype(args)(args)... );
};
};
auto ycomb = ycomb0( ycombx_ref );
现在传递给lambda的self
本身不需要自身传递:
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(a, n-1);
});