funciones examples c++ c++11 lambda auto

examples - C++ 11 ¿Cambiar `auto` Lambda a un Lambda diferente?



lambda examples c++ (5)

Digamos que tengo la siguiente variable que contiene un lambda:

auto a = [] { return true; };

Y quiero a regreso false tarde. ¿Podría hacer algo en la línea de esto?

a = [] { return false; };

Esta sintaxis me da los siguientes errores:

binary ''='' : no operator found which takes a right-hand operand of type ''main::<lambda_a7185966f92d197a64e4878ceff8af4a>'' (or there is no acceptable conversion) IntelliSense: no operator "=" matches these operands operand types are: lambda []bool ()->bool = lambda []bool ()->bool

¿Hay alguna manera de lograr algo como esto? Me gustaría cambiar la variable auto a una lambda diferente. Soy un principiante, por lo que puede que me falte algo de conocimiento sobre auto o lambdas. Gracias.


Cada expresión lambda crea un nuevo tipo único, por lo que el tipo de su primer lambda es diferente del tipo de su segundo ( example ). Además, el operador de asignación de copias de un lambda se define como eliminado ( example ), por lo que no puede hacer esto por partida doble. Para un efecto similar, puede tener a be std::function aunque le costará algo de rendimiento

std::function<bool()> a = [] { return true; }; a = [] { return false; };


Cada lambda tiene un tipo diferente, por lo que no puede cambiarlo. Podría usar una std::function para mantener un objeto llamable arbitrario, que se puede cambiar a voluntad.

std::function <bool ()> a = [] { return true; }; a = [] { return false; };


Desde C++17 puede hacer que se deduzca el parámetro std::function template gracias a la deducción de argumentos de la plantilla de clase . Incluso funciona con la captura de lambdas:

int a = 24; std::function f = [&a] (int p) { return p + a; }; f = [&a] (int p) { return p - a; }; f = [] (int p) { return p; };

Esto es útil con firmas más complejas y aún más con tipos de devolución deducidos.


Podemos usar la llamada retrospectiva para convertir lambda a std :: function:

template<typename T> struct memfun_type { using type = void; }; template<typename Ret, typename Class, typename... Args> struct memfun_type<Ret(Class::*)(Args...) const> { using type = std::function<Ret(Args...)>; }; template<typename F> typename memfun_type<decltype(&F::operator())>::type FFL(F const &func) { // Function from lambda ! return func; }

Después de eso podremos hacerlo (ya que ''a'' es std :: function type now):

auto a = FFL([] { return false; }); a = FFL([] { return true; });


Un Lambda se puede convertir en un puntero de función utilizando el operador unario + manera:

+[]{return true;}

siempre que el grupo de captura esté vacío y no tenga argumentos auto . 1

Si hace esto, puede asignar diferentes lambdas a la misma variable siempre que las lambdas tengan la misma firma.

En tu caso,

auto a = +[]{return true;}; a = +[]{return false;};

Ejemplo vivo en Coliru

compilaría y actuaría como usted espera. 2 Puede usar los punteros de función de la misma manera que espera usar un lambda, ya que ambos actuarán como functors .

1. En C ++ 14, puede declarar lambdas con auto como tipo de argumento, como [](auto t){} . Estas son lambdas genéricas , y tienen un operator() plantilla operator() . Dado que un puntero de función no puede representar una función con plantilla, el truco + no funcionará con lambdas genéricas.

2. Técnicamente, no necesita el segundo operador + en la tarea. La lambda se convertiría al tipo de puntero de función en la asignación. Aunque me gusta la consistencia.