Делаю рекурсивную лямбда (для определенности - факториал). Вот так все отлично работает: std::function f = [&f](int n) -> int { return (n) ? n*f(n-1) : 1 } А вот так - ни в какую: auto h = [&h](int n) -> int { return (n) ? n*h(n-1) : 1 } хотя, казалось бы, тип h вывести нет никакой проблемы - специально даже указал возвращаемый int. В чем настолько большая разница, что вывод типа не срабатывает? Казалось бы, из определения (int)->int тип очевиден, после чего можно использовать его в теле лямбды? И второй вопрос - интересно, а можно ли извратиться до такой степени, чтобы написать анонимную рекурсивную лямбду, т.е. без сохранения ее в переменной - что-то вроде cout << [&](int n)->int{ ..... }(6) << endl <br>P.S. Решение для второго вопроса нашлось - использовать внутри неименованной лямбды именованную (например, тот же f выше), но это все же не совсем то, что хотелось :)
Ответ Начиная с C++23 у нас появилась возможность явного указания this в аргументах функции (которая предполагает наличие оного) (deducing this), а это, в свою очередь, позволяет создать рекурсивную лямбду: auto lambda = [](this const auto& self, int n) -> int { return (n) ? n*self(n-1) : 1 } Нижепредставленный текст представляет собой старый ответ, который актуален для более старых версий C++. Сохранён для истории.
Разыграем спектакль, главные действующие лица: компилятор и компилятор, и компилятор, и ... Компилятор встречает следующую строчку: auto h = [&h](int n) -> int { return (n) ? n*h(n-1) : 1 } — Ага — говорит, компилятор. Мне нужно сгенерировать класс под лямбду, секундочку: class lkdlkhbahbahkl_danfaksdf_lamba { public: int operator()(int n) const { return (n) ? n*h(n-1) : 1 } private: ???? h } Компилятор встречает первое препятствие, нужно объявить член класса с именем h, но его тип не известен. Надо спросить компилятор! — Компилятор, скажи мне тип переменной h! — воскликнул компилятор. — Секундочку — ответил компилятор. А сам подумал, я ведь тип то и не знаю, спрошу-ка я компилятор, что там за тип у этой лямды. — Компилятор, скажи мне тип лямбды, у меня компилятор спрашивает, ему надо там член класса создать, а он тип не знает — говорит компилятор — Нет проблем — отвечает компилятор, сейчас, только лямбду сгенерирую... Ну Вы поняли, как наш спектакль будет продолжен?
Касательно второго вопроса: анонимную рекурсивную лямбду создать нельзя. Если что-то не имеет имени, как сделать рекурсивный вызов?