C++ Weekly Episode 162 Recursive Lambdas

若使用常规的递归方式来实现一个斐波那契数列的 lambda 函数, 如下:

1
2
3
4
5
6
7
8
9
10
11
constexpr auto fib = [](int input) {
if (input < 2)
return 1;

return fib(input - 1) + fib(input - 2);
};

int main()
{
return fib(3);
}

此时编译器将报错, 因为 lambda 内在调用 fib 时, 还不知道 fib 完整的定义:

1
2
error: variable 'fib' declared with deduced type 'const auto' cannot appear in its own initializer
return fib(input - 1) + fib(input - 2);

解决方式之一, 将 lambda 自身作为作为一个参数传入:

1
2
3
4
5
6
7
8
9
10
11
12

constexpr auto fib = [](const auto fib, int input) {
if (input < 2)
return 1;

return fib(fib, input - 1) + fib(fib, input - 2);
};

int main()
{
return fib(fib, 5);
}

但是调用时传入自身又显得略微多余, 不够优雅. 还可以包装一下 lambda , 这样我们只需要传入一个参数就可以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
constexpr auto fib_ = [](const auto fib, int input) {
if (input < 2)
return 1;

return fib(fib, input - 1) + fib(fib, input - 2);
};

constexpr auto fib = [](int input) {
return fib_(fib_, input);
};s

int main()
{
return fib(5);
}

不过, 还是存在两个 lambda 定义, 我们可以直接一步到位:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
constexpr auto fib = [](int input) {
constexpr auto fib_ = [](const auto fib, int input) {
if (input < 2)
return 1;

return fib(fib, input - 1) + fib(fib, input - 2);
};

return fib_(fib_, input);
};

int main()
{
return fib(5);
}