Lambda函数可以递归吗?

87

可能是重复的问题:
C++0x中的递归lambda函数

这里是一个普通的递归函数:

int fak(int n)
{
    return (n <= 1) ? 1 : n * fak(n - 1);
}

我该如何将这样一个递归函数写成lambda函数?

[](int n) { return (n <= 1) ? 1 : n * operator()(n - 1); }
// error: operator() not defined

[](int n) { return (n <= 1) ? 1 : n * (*this)(n - 1); }
// error: this wasn't captured for this lambda function

有没有一个表达式可以表示当前 lambda,以便它可以递归地调用自己?

1
可能存在巨大的std :: function开销,也可能使用多态lambda表达式。 - ipc
@MichaelBurr,你的链接很棒。 - chris
2
糟糕 - 我不小心删掉了我的评论。这是回到链接:http://blogs.msdn.com/b/vcblog/archive/2008/11/18/stupid-lambda-tricks.aspx - Michael Burr
@MichaelBurr,这很有趣。我觉得你不小心删除了你的评论的想法是可笑的,但我可以理解这样做是多么容易:p - chris
我只是把这个放在这里 http://www.slideshare.net/adankevich/c11-15621074 29张幻灯片 - innochenti
为什么不使用Y组合子?http://rosettacode.org/wiki/Y_combinator#C.2B.2B - kerzol
1个回答

122

是的,它们可以。从C++23开始,您可以使用显式this参数:

auto factorial = [](this auto self, int i) 
{ 
    return (i == 1) ? 1 : i * self(i - 1); 
};

在之前的C++标准中,您可以将lambda存储在变量中并引用该变量(尽管您无法将该变量的类型声明为auto,而必须使用std::function对象)。例如:

std::function<int (int)> factorial = [&] (int i) 
{ 
    return (i == 1) ? 1 : i * factorial(i - 1); 
};

2
我认为 factorial 需要被引用捕获,但我不是100%确定。 - ildjarn
31
注意,这样的函数不能安全地返回。 - R. Martinho Fernandes
4
不错的观点,这将通过引用已超出作用域的本地对象。我猜你仍然可以使用shared_ptr,但那可能有点过分追求完美。 - Andy Prowl
1
@rikimaru2013 同时,为了完整起见,需要注意使用专用结构类型而不是 lambda 的等效代码将通过使用“this”来支持该功能。 - R. Martinho Fernandes
3
为什么无法使用 auto 关键字作为 lambda 表达式的类型?只要我在 lambda 函数体中指定返回类型,我就认为应该可以这样做。C++ 真是愚蠢 :( - Lightness Races in Orbit
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接