Подтвердить что ты не робот

Вызовите С++ рекурсивную лямбду в той же строке, где она объявлена

Это, в основном, вопрос типа одного типа лайнера, я бы обычно писал этот код в нескольких строках в любом случае для удобства чтения.

Итак, мой вопрос: могу ли я назвать рекурсивную лямбду в том же самом утверждении, где она определена?

Итак, вместо этого:

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 определен.

4b9b3361

Ответ 1

Позвольте мне взглянуть на мир функционального программирования, где люди обычно используют комбинаторы для работы с рекурсивными лямбдами. В прошлом году было предложение

Основная идея здесь заключается в том, что Y-combinator представляет собой функцию более высокого порядка, которая обертывает лямбда, которая передается "самой" в качестве первого аргумента. Комбинатор позаботится о том, чтобы отключить аргумент self для всех вызовов лямбда.

Вы можете .

Ответ 2

В одном заявлении, которое объявляет несколько переменных;-)
В основном не то, что вы хотите:

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

Демо

Ответ 3

На самом деле вы можете. Вот полный пример, который компилируется и работает отлично с помощью 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) была бы для кодов гольфа или запутанных программных соревнований, но не соответствовала бы моим стандартам для производственного кода.

Ответ 4

То, что вы по существу запрашиваете, это создать временный экземпляр 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);

error: expected ', или'; до '(токен

Указание на ( of (n).

См. ответ @Jarod42 для жизнеспособного обходного пути, если вы не возражаете против инициализации дополнительных переменных.

В качестве альтернативы это будет работать, хотя для этого необходимо использовать отдельное объявление и назначение переменных:

function<void(int)> f; f = [&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; }, f(n);

Демо

Ответ 5

Не уверен, считаете ли вы его действительным, так как он не использует лямбда-функции, но он все еще однострочный и не оставляет временных переменных за;)

struct {
  struct R {
    R(int i) {
      if (i>1) { cout << "func(a, "; R(i-1); cout << ")"; }
      else cout << "a";
    }
  } r;
} f{n};