Teníamos una función que usaba una lambda interna que no capturaba, por ejemplo:
void foo() {
auto bar = [](int a, int b){ return a + b; }
// code using bar(x,y) a bunch of times
}
Ahora la funcionalidad implementada por el lambda se hizo necesaria en otros lugares, por lo que voy a sacar el lambda del foo()
alcance global / espacio de nombres. Puedo dejarlo como lambda, convirtiéndolo en una opción de copiar y pegar, o cambiarlo a una función adecuada:
auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2
void foo() {
// code using bar(x,y) a bunch of times
}
Cambiarlo a una función adecuada es trivial, pero me hizo preguntarme si hay alguna razón para no dejarlo como una lambda. ¿Hay alguna razón para no usar lambdas en todas partes en lugar de funciones globales "regulares"?
Respuestas:
Hay una razón muy importante para no usar lambdas globales: porque no es normal.
La sintaxis de la función regular de C ++ ha existido desde los días de C. Los programadores han sabido durante décadas qué significa dicha sintaxis y cómo funcionan (aunque es cierto que la descomposición de la función de puntero a veces muerde incluso a programadores experimentados). Si un programador de C ++ de cualquier nivel más allá del "novato absoluto" ve una definición de función, sabe lo que está obteniendo.
Una lambda global es una bestia completamente diferente. Tiene un comportamiento diferente al de una función regular. Las lambdas son objetos, mientras que las funciones no lo son. Tienen un tipo, pero ese tipo es distinto del tipo de su función. Etcétera.
Así que ahora, has elevado el listón en la comunicación con otros programadores. Un programador de C ++ necesita comprender lambdas si va a comprender qué está haciendo esta función. Y sí, esto es 2019, por lo que un programador decente de C ++ debería tener una idea de cómo es una lambda. Pero sigue siendo una barra más alta.
E incluso si lo entienden, la pregunta en la mente de ese programador será ... ¿por qué el escritor de este código lo escribió de esa manera? Y si no tiene una buena respuesta para esa pregunta (por ejemplo, porque quiere prohibir explícitamente la sobrecarga, como en los puntos de personalización de Rangos), entonces debe usar el mecanismo común.
Prefiere las soluciones esperadas a las nuevas cuando sea apropiado. Use el método menos complicado para transmitir su punto de vista.
fuente
Puedo pensar en algunas razones por las que desearía evitar las lambdas globales como reemplazos directos para las funciones regulares:
"¿Por qué no debería usar lambdas para reemplazar a los functores con estado (clases)?"
fuente
std::integral_constant
para eso ...Después de preguntar, pensé en una razón para no hacer esto: dado que estas son variables, son propensas al Fiasco de orden de inicialización estática ( https://isocpp.org/wiki/faq/ctors#static-init-order ), que podría causar errores en la línea.
fuente
constexpr
lambdas ... el punto real es: Sólo tiene que utilizar una función.Un problema de cierto nivel de complejidad requiere una solución de al menos la misma complejidad. Pero si hay una solución menos compleja para el mismo problema, entonces realmente no hay justificación para usar la más compleja. ¿Por qué introducir la complejidad que no necesitas?
Entre una lambda y una función, una función es simplemente el tipo menos complejo de entidad de las dos. No tiene que justificar no usar una lambda. Tienes que justificar el uso de uno. Una expresión lambda introduce un tipo de cierre, que es un tipo de clase sin nombre con todas las funciones de miembros especiales habituales, un operador de llamada de función y, en este caso, un operador de conversión implícito a puntero de función, y crea un objeto de ese tipo. Copiar-inicializar una variable global de una expresión lambda simplemente hace mucho más que solo definir una función. Define un tipo de clase con seis funciones declaradas implícitamente, define dos funciones de operador más y crea un objeto. El compilador tiene que hacer mucho más. Si no necesita ninguna de las características de una lambda, entonces no use una lambda ...
fuente
Las lambdas son funciones anónimas .
Si está utilizando una lambda con nombre, significa que básicamente está utilizando una función anónima con nombre. Para evitar este oxímoron, también podrías usar una función.
fuente
Solíamos usar funciones en lugar de functor global, por lo que rompe la coherencia y el Principio de menor asombro .
Las principales diferencias son:
fuente