在声明它的同一行中调用C ++递归lambda

时间:2017-03-14 21:16:46

标签: c++ c++11 recursion lambda

这主要是一种单线型问题,出于可读性原因,我通常会将这些代码写成多行。

所以我的问题是我可以在定义它的同一语句中调用递归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的同一行中调用该函数。

5 个答案:

答案 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));

Demo

答案 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)

Demo

答案 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};