c++ - recursiva - recursividad en programacion
Llame a C++ lambda recursiva en la misma lĂnea donde se declara. (5)
Esto es principalmente una pregunta de estilo de línea, normalmente escribiría este código en múltiples líneas de todas formas por razones de legibilidad.
Entonces, mi pregunta es ¿puedo llamar a la lambda recursiva en la misma declaración donde se define?
Así que en lugar de esto:
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);
llamar a la función con n
en la misma línea donde se define f.
De hecho, usted puede. Aquí hay un ejemplo completo que compila y funciona bien con 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);
}
Sin embargo, no creo que sea una buena idea usar esto: la construcción , trash = (..., f)
estaría en orden para el golf de código o los concursos de programación confusos, pero no cumpliría con mis estándares de código de producción.
En una declaración que declara varias variables ;-)
En su mayoría no es lo que quieres:
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));
Lo que esencialmente estás pidiendo es crear una instancia temporal de std::function
y luego invocar operator()
en ese objeto en la misma declaración. Ambos de estos no compilan para mí con el mismo error cuando intento eso:
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: esperado '','' o '';'' antes de ''('' token
Señalando a la (
de (n)
.
Vea la respuesta de @Jarod42 para una solución viable, si no le importa la inicialización de la variable adicional.
Alternativamente, esto funcionaría, aunque tiene que usar una declaración y asignación de variables separadas:
function<void(int)> f; f = [&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; }, f(n);
No estoy seguro si lo consideras válido ya que no usa las funciones lambda, pero sigue siendo una sola línea y no deja atrás variables temporales;)
struct {
struct R {
R(int i) {
if (i>1) { cout << "func(a, "; R(i-1); cout << ")"; }
else cout << "a";
}
} r;
} f{n};
Permítame ofrecerle un vistazo al mundo de la programación funcional, donde las personas usualmente usan combinators para lidiar con las lambdas recursivas. Hubo una propuesta (P0200r0) el año pasado para agregar un simple combinador en Y a la biblioteca estándar.
Dejando de lado la pregunta de si es una buena idea hacer esto, esto le permitiría escribir e invocar un lambda recursivo como este:
y_combinator([](auto self, int i){
if (i>1) {
std::cout << "func(a, ";
self(i-1);
std::cout << ")";
} else {
std::cout << "a";
}
})(6);
La idea básica aquí es que el combinador y es una función de orden superior que envuelve un lambda que se pasa "a sí mismo" como primer argumento. El combinador se encarga de envolver el argumento propio para todas las invocaciones de la lambda.
Puedes probarlo en coliru .