tipo sintaxis puede funciones expresiones expresion español ejemplos delegado convertir anonimas c++ lambda c++11 break nested-loops

c++ - puede - lambda sintaxis



¿Es este un uso válido(ab) de expresiones lambda? (4)

¿De qué manera es eso una mejora sobre

void frgleTheBrgls() { while(CheckCondition()) { for(;;) { if(!CheckOtherCondition()) return; // do stuff... } // do stuff... } } int main() { frgleTheBrgls(); std::cout << "yep, broke out of it/n"; }

Esto es muy conocido (funciones, ya sabes, como en BASIC), más claro (el algoritmo tiene un buen nombre que explica lo que hace), y hace exactamente lo mismo que el tuyo.

Especialmente la versión de función carece debido al contexto faltante donde se llaman los bucles, ya que necesitaría pasar todo lo que necesita en los bucles como parámetros.

Veo eso como una ventaja. Ves exactamente lo que se necesita para enredar los brgls. Explicidad, cuando se programa, a menudo es algo bueno.

Como todos sabemos, no es tan fácil break de un bucle anidado de un bucle externo sin:

Sin embargo, debes admitir que todos son un poco torpes. Especialmente la versión de función carece debido al contexto faltante donde se llaman los bucles, ya que necesitaría pasar todo lo que necesita en los bucles como parámetros.
Además, el segundo empeora para cada ciclo anidado.
Por lo tanto, personalmente, todavía considero que la versión goto es la más limpia.

Ahora, pensando en todo C ++ 0x y esas cosas, la tercera opción me trajo esta idea utilizando expresiones lambda:

#include <iostream> bool CheckCondition(){ return true; } bool CheckOtherCondition(){ return false; } int main(){ [&]{while(CheckCondition()){ for(;;){ if(!CheckOtherCondition()) return; // do stuff... } // do stuff... }}(); std::cout << "yep, broke out of it/n"; }

( Ejemplo en Ideone. )

Esto permite la belleza semántica de un return simple que ofrece la tercera opción sin sufrir los problemas de contexto y ser (casi) tan limpio como la versión goto . También es incluso más corto (en cuanto a caracteres) que cualquiera de las opciones anteriores.

Ahora, he aprendido a mantener mi alegría después de encontrar hermosos (ab) usos del idioma, porque casi siempre hay algún tipo de inconveniente. ¿Hay alguno en este? ¿O hay un mejor acercamiento al problema?


Perfectamente válido en mi opinión. Aunque prefiero asignar la mía con nombres, lo que hace que el código sea más autodocumentado, es decir,

int main(){ auto DoThatOneThing = [&]{while(CheckCondition()){ for(;;){ if(!CheckOtherCondition()) return; // do stuff... } // do stuff... }}; DoThatOneThing(); std::cout << "yep, broke out of it/n"; }


Por favor, no hagas eso en un proyecto que estoy administrando. Eso es un abuso incómodo de lambdas en mi opinión.

Usa un goto donde un goto es útil.


Una desventaja con su sintaxis propuesta: no puede tener más de 2 bucles anidados. La sintaxis ''goto'' permite esto:

int main() { for (;;) { for (;;) { for (;;) { if (CheckCondition1()) goto BREAK_ON_COND1; if (CheckCondition2()) goto BREAK_ON_COND2; if (CheckCondition3()) break; // Do stuff when all conditions are false } // Do stuff when condition 3 becomes true } BREAK_ON_COND2: // Do stuff when condition 2 becomes true } BREAK_ON_COND1: // When condition 1 becomes true std::cout << "yep, broke out of it/n"; }