如何制作一个递归的lambda函数,它接受2个参数而不是1?

问题描述 投票:1回答:3

我已经知道如何创建一个递归lambda函数,它接受一个参数,如计算一个数字的阶乘,但我尝试使用lambda(作为一种做法)制作一个递归幂函数,但在函数中取两个参数会导致错误

这个代码:

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
c++ c++11 recursion lambda std-function
3个回答
4
投票

你必须使用

std::function <int(int, int)> power = [&](int a, int n) { ... }

用于使用两个参数的函数。

改进建议:

Make sure you deal with n = 0 correctly.

用于

return (n <= 1) ? a : a*power(a, n-1);

是不正确的。当使用a调用函数时,您将返回n = 0

使用

return (n == 0) ? 1 : a*power(a, n-1);

Use unsigned int for 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);
};

4
投票

也许

std::function <int(int, int)> power = [&](int a, int n) ....
// ...................^^^^^

?

我的意思是:如果power是一个用接收两个整数的lambda初始化的std::function,并且用作接收两个整数的函数,可能就是将它声明为接收两个整数,而不仅仅是一个整数。


0
投票

你的递归lambda遇到了问题;它需要创建它的确切变量才能存在,或者它是UB来调用它。

auto ycomb = [](auto&&f){ return [f=f](auto&&...args){ return f(f, decltype(args)(args)...); }; };

这个小玩具修复了那个bug。

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);
});

Live example

© www.soinside.com 2019 - 2024. All rights reserved.