这主要是一种单线型问题,出于可读性原因,我通常会将这些代码写成多行。
所以我的问题是我可以在定义它的同一语句中调用递归lambda吗?
所以不要这样:
int n=3;
function<void(int)> f {[n,&f](int i){if (i>1) { cout << "func(a, "; f(i-1); cout << ")";} else cout << "a";}};
f(n);
使用n
在定义f的同一行中调用该函数。
答案 0 :(得分:14)
在一个声明几个变量的声明中;-)
大多数情况下不是你想要的:
std::function<void(int)>
f {[&f](int i){
if (i>1) {
std::cout << "func(a, "; f(i-1); std::cout << ")";}
else
std::cout << "a";
}},
dummy((f(3), nullptr));
答案 1 :(得分:6)
事实上,你可以。这是一个完整的示例,它使用g++ -std=c++11
编译并运行良好:
#include <iostream>
#include <functional>
int main() {
std::function<int(int)> f = ([&f](int i){ return i?f(i-1)*i:1; }), trash = (std::cout << f(3) << std::endl, f);
}
但是,我认为实际使用它并不是一个好主意:构造, trash = (..., f)
将用于代码高尔夫或模糊编程竞赛,但不符合我的生产代码标准。
答案 2 :(得分:6)
让我一瞥函数式编程世界,人们通常使用combinators来处理递归的lambdas。去年有一个proposal (P0200r0)将一个简单的Y-combinator添加到标准库中。
不考虑这样做是否是个好主意的问题,这将允许你编写和调用这样的递归lambda:
y_combinator([](auto self, int i){
if (i>1) {
std::cout << "func(a, ";
self(i-1);
std::cout << ")";
} else {
std::cout << "a";
}
})(6);
这里的基本思想是y-combinator是一个高阶函数,它包含一个lambda,它作为第一个参数传递给'本身'。组合器负责将自变量包装为lambda的所有调用。
你可以try it in coliru。
答案 3 :(得分:3)
您实际要求的是创建std::function
的临时实例,然后在同一语句中对该对象调用operator()
。当我尝试使用相同的错误时,这两个都无法为我编译:
function<void(int)> f{[&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; }}(n);
function<void(int)> f([&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; })(n);
错误:在'('token
之前'预期','或';'
指向(
的{{1}}。
如果您不介意额外的变量初始化,请参阅@ Jarod42的答案以获得可行的解决方法。
或者,这可行,但它必须使用单独的变量声明和赋值:
(n)
答案 4 :(得分:2)
不确定你认为它是否有效,因为它没有使用lambda函数,但它仍然是单行并且没有留下时间变量;)
struct {
struct R {
R(int i) {
if (i>1) { cout << "func(a, "; R(i-1); cout << ")"; }
else cout << "a";
}
} r;
} f{n};