如何制作一个采用 2 个参数而不是 1 个参数的递归 lambda 函数?
How to make a recursive lambda function that takes 2 arguments not 1?
我已经知道如何制作一个采用一个参数的递归 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
也许
std::function <int(int, int)> power = [&](int a, int n) ....
// ...................^^^^^
?
我的意思是:如果 power
是一个 std::function
,它使用接收 两个 整数的 lambda 进行初始化,并用作接收函数两个整数,也许是声明它接收两个个整数,而不是一个。
你必须使用
std::function <int(int, int)> power = [&](int a, int n) { ... }
用于使用两个参数的函数。
改进建议:
确保您正确处理 n = 0
。
使用
return (n <= 1) ? a : a*power(a, n-1);
不对。当使用 n = 0
.
调用函数时,您将返回 a
使用
return (n == 0) ? 1 : a*power(a, n-1);
对 n
使用 unsigned int
。
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);
};
您的递归 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
本身不需要传递 self:
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(a, n-1);
});
我已经知道如何制作一个采用一个参数的递归 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
也许
std::function <int(int, int)> power = [&](int a, int n) ....
// ...................^^^^^
?
我的意思是:如果 power
是一个 std::function
,它使用接收 两个 整数的 lambda 进行初始化,并用作接收函数两个整数,也许是声明它接收两个个整数,而不是一个。
你必须使用
std::function <int(int, int)> power = [&](int a, int n) { ... }
用于使用两个参数的函数。
改进建议:
确保您正确处理 n = 0
。
使用
return (n <= 1) ? a : a*power(a, n-1);
不对。当使用 n = 0
.
a
使用
return (n == 0) ? 1 : a*power(a, n-1);
对 n
使用 unsigned int
。
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);
};
您的递归 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
本身不需要传递 self:
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(a, n-1);
});