parameter geeksforgeeks funciones funcion example cpp c++ c++11 lambda functor

funciones - lambda c++ geeksforgeeks



Cuándo usar funtores sobre lambdas (4)

Consideraría usar un functor sobre una lambda cuando

  • quiere más de una instancia.
  • tiene que hacer un manejo avanzado de los recursos.
  • necesita referirse al functor como un tipo. Por ejemplo, pasarlo como un parámetro de plantilla.
  • (relacionado) puede dar un nombre significativo y generalmente útil al tipo (a diferencia de la instancia ).
  • encuentre que la lógica puede escribirse más limpia cuando se divide en subfunciones. En una lambda, tenemos que escribir todo en una sola función.

¿Hay alguna vez una situación en la que tenga más sentido crear un functor que usar una lambda?

Sé que mi pregunta es, efectivamente, el reverso de cuándo usar una lambda sobre un functor , pero no puedo pensar en una situación en la práctica donde un funtor sería preferido sobre un lambda. Tiene alguna idea sobre esto?


Podría pensar en dos casos:

  1. Cuando el funtor lleva el estado interno, entonces hay un problema de tiempo de vida no trivial con el funtor. Mantiene "algo" entre los usos

  2. Cuando tiene que usar el mismo código en todas partes, escribir y mantenerlo como un funtor en su propio encabezado podría ser una buena idea desde el punto de vista del mantenimiento


Un lambda es un funtor, solo se define con una sintaxis más corta.

El problema es que esta sintaxis es limitada. No siempre le permite resolver un problema de la manera más eficiente y flexible, o en absoluto. Hasta C ++ 14, el operator() ni siquiera podría ser una plantilla.

Además, un lambda tiene exactamente un operator() . No puede proporcionar varias sobrecargas para distinguir, por ejemplo, los tipos de argumentos:

struct MyComparator { bool operator()( int a, int b ) const {return a < b;} bool operator()( float a, float b ) const {return /*Some maths here*/;} };

.. o categoría de valor del argumento del objeto (es decir, el objeto de cierre que se llama). Tampoco puede definir funciones de miembros especiales, incluidos constructores y destructores: ¿qué ocurre si un funtor se responsabiliza de los recursos?

Otro problema con lambdas es que no pueden ser recursivos. Por supuesto, las funciones normales (incluidas las funciones del operador) pueden ser.

Tenga en cuenta también que las lambdas no son aptas para usar como comparadores para contenedores asociativos o eliminadores de punteros inteligentes: no puede pasar directamente el tipo de cierre como un argumento de plantilla y necesita construir el miembro de contenedores desde otro objeto de cierre. (¡Los tipos de cierre no tienen un constructor predeterminado!). Para un map alcance de bloque que no es demasiado complicado:

auto l = [val] (int a, int b) {return val*a < b;}; std::map<int, int, decltype(l)> map(l);

Ahora, ¿qué sucede si su map es un miembro de datos ? ¿Qué argumento de plantilla, qué inicializador en la lista de inicialización de constructores? Tendría que usar otro miembro de datos estáticos, pero dado que tiene que definirlo fuera de la definición de clases que posiblemente sea feo.

En resumen : Lambdas no son útiles para escenarios más complejos porque no fueron hechos para ellos. Proporcionan una forma breve y concisa de crear objetos de funciones simples para situaciones correspondientemente simples.


Una lambda no se puede usar en un contexto no evaluado . Un ejemplo particularmente artificial es robado de Shafik''s respuesta de Shafik''s :

  1. En muchos casos es inútil ya que cada lambda tiene un tipo único, el ejemplo hipotético dado:

    template<typename T, typename U> void g(T, U, decltype([](T x, T y) { return x + y; }) func); g(1, 2, [](int x, int y) { return x + y; });

    El tipo de lambda en la declaración y la llamada son diferentes ( por definición ) y, por lo tanto, esto no puede funcionar.

Entonces, incluso una lambda con sintaxis idéntica no puede ser utilizada en lugar de otra. Un functor funcionará en este caso.