2011-01-10 11 views
8

Estoy seguro de obtener la esencia general de las construcciones, pero no puedo ver el propósito de ellas en C++. He leído las publicaciones anteriores sobre el tema aquí en SO y en otros lugares, pero no veo por qué deberían ser una nueva función de idioma.Diferencia entre C++ 0x lambdas y operador(), cierre y functor

Las cosas que me gustaría responder es thusly

  • ¿Cuál es la diferencia entre un lambda y un argumento de plantilla aceptar una función/funtor.

  • ¿Es un cierre solo un funtor con algún estado de objeto establecido (scope?)?

  • ¿Cuál es la "aplicación asesina" para estos constructos? o tal vez el caso de uso típico?
+0

Se necesitan más de 5 páginas en el estándar en 5.1.2 para describir lambdas. La única forma de dar una respuesta breve si hay una pregunta directa. –

+2

La presentación "Lambdas, Lambdas Everywhere" de Herb Sutter en PDC10 hace un muy buen trabajo explicando lambdas en C++. Puede encontrar el enlace aquí: http://herbsutter.com/2010/10/30/pdc-languages-panel-andshortened-lambdas-talk/ o directamente http://bit.ly/dcJcXN –

+0

@Eugen Gracias por los enlaces Eugen –

Respuesta

17

Las lambdas son en realidad solo azúcar sintáctica para un functor. Puede hacerlo todo usted mismo: definir una nueva clase, hacer que las variables miembro contengan los valores capturados y las referencias, conectarlos al constructor, escribir operator()() y, finalmente, crear una instancia y pasarla. O podrías usar una lambda que tenga 1/10 de código y funcione de la misma manera.

Las lambdas que no se capturan se pueden convertir a indicadores de función. Todas las lambdas se pueden convertir a std::function, u obtener su propio tipo único que funciona bien en algoritmos de plantillas que aceptan un funtor.

+1

¿puedes tener funtores anónimos? ¿Pueden los funtores deducir el tipo de devolución? ¿Pueden los funtores captar implícitamente el contexto y buscar como lambdas? ¿Puedes crear un functor en lugar de expresión? –

+0

Y esta es la forma en que estoy enseñando functors atm. Realmente no me preocupa la cantidad de código, ya que es fácil de explicar cuando surge el tema. También parece bastante elegante en el viejo estilo. –

+0

Entonces, ¿cuál es la aplicación asesina que hizo de las lambdas una parte del lenguaje? 1/10 del código no es un punto de venta para mí. –

10

Ok, en realidad estás haciendo un montón de preguntas diferentes, posiblemente porque no estás completamente familiarizado con la terminología. Intentaré responder a todos.

¿Cuál es la diferencia entre un lambda y "operator()"? - Cambiemos esto a "¿Cuál es la diferencia entre un lambda y un objeto con operator()?"

Básicamente, nada. La principal diferencia es que una expresión lambda crea un objeto funcional, mientras que un objeto con un operador() ES un objeto funcional. El resultado final es lo suficientemente similar como para considerar lo mismo, una entidad que puede invocarse con la sintaxis (params).

¿Cuál es la diferencia entre un cierre y un functor? Esto también es bastante confuso. Por favor revise este enlace:

http://en.wikipedia.org/wiki/Closure_(computer_programming) http://en.wikipedia.org/wiki/Closure_(computer_programming)#C.2B.2B

Por lo tanto, como se puede ver, el cierre es una especie de "funtor" que se define dentro de un alcance tal que absorbe las variables disponibles para que dentro de ese ámbito . En otras palabras, es una función que se construye sobre la marcha, durante el funcionamiento del programa y ese proceso de construcción se parametriza mediante los valores de tiempo de ejecución del ámbito que lo contiene. Entonces, en C++ los cierres son lambdas que usan valores dentro de la función que construye el lambda.

¿Cuál es la diferencia entre un argumento lambda y una plantilla que acepta una función/functor? - Esto está nuevamente confundido. La diferencia es que no son nada iguales, realmente. Un "argumento" de plantilla que acepta una función/functor ya es una redacción confusa, así que supondré por "argumento" que quiere decir "función", porque los argumentos no aceptan nada. En este caso, aunque un lambda puede aceptar un functor como argumento, no puede ser templado, uno. Dos, generalmente el lambda es el que se pasa como argumento para una función que acepta un argumento de functor.

¿Es un cierre solo un funtor con algún estado de objeto establecido (scope?)?

Como puede ver en el enlace de arriba, no. De hecho, un cierre ni siquiera tiene estado, realmente. Se construye un cierre basado en el estado de alguna otra entidad que lo construyó, dentro de ese functor aunque este no es estado, es la construcción misma del objeto.

¿Cuál es la "aplicación asesina" para estos constructos? o tal vez el caso de uso típico?

Voy a volver a escribir que, "¿Por qué estas cosas son útiles?"

Bueno, en general, la capacidad de tratar cualquier objeto como una función si tiene operador() es extremadamente útil para una gran variedad de cosas. Por un lado, nos permite extender el comportamiento de cualquier algoritmo stdlib mediante el uso de objetos o funciones gratuitas. Es imposible resumir la gran cantidad de utilidades que tiene.

Más específicamente hablando de expresiones lambda, simplemente hacen que este proceso sea aún más fácil. Las limitaciones impuestas por las definiciones de objeto hicieron que el proceso de usar algoritmos stdlib fuera ligeramente ineficiente en algunos casos (desde una perspectiva de uso de desarrollo, no de eficiencia de programa). Por un lado, en ese momento, al menos, cualquier objeto pasado como parámetro a una plantilla tenía que definirse externamente. Creo que eso también está cambiando, pero aún así ... tener que crear objetos enteros solo para realizar cosas básicas, que solo se usan en un solo lugar, es inconveniente. Las expresiones Lambda permiten que la definición sea bastante fácil, dentro del ámbito del lugar donde se usa, etc., etc.

+0

Me gusta mucho tu respuesta +1. pero el "Bueno, en general, la capacidad de tratar cualquier objeto como una función si tiene operador() es extremadamente útil", mucho me lleva de vuelta a mi pregunta original. –

+0

Creo que necesitarás señalar tu pregunta original porque pude ver varias y les di la mejor respuesta posible a todas. –

+0

Era una pregunta de tres partes y me disculpo por eso. Tu respuesta me dio una buena idea. Realmente aprecio tu respuesta –

Cuestiones relacionadas