Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a valid (ab)use of lambda expressions?

Like we all know, it's not that easy to break from a nested loop out of an outer loop without either:

  • a goto (Example code.)
  • another condition check in the outer loop (Example code.)
  • putting both loops in an extra function and returning instead of breaking (Example code.)

Though, you gotta admit, all of those are kinda clumsy. Especially the function version lacks because of the missing context where the loops are called, as you'd need to pass everything you need in the loops as parameters.
Additionally, the second one gets worse for each nested loop.
So, I personally, still consider the goto version to be the cleanest.


Now, thinking all C++0x and stuff, the third option brought me this idea utilizing lambda expressions:

#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";
}

(Example at Ideone.)

This allows for the semantic beauty of a simple return that the third option offers while not suffering from the context problems and being (nearly) as clean as the goto version. It's also even shorter (character-wise) than any of the above options.


Now, I've learned to keep my joy down after finding beautiful (ab)uses of the language, because there's almost always some kind of drawback. Are there any on this one? Or is there even a better approach to the problem?

like image 871
Xeo Avatar asked May 20 '11 21:05

Xeo


2 Answers

Perfectly valid in my opinion. Though I prefer to assign mine with names, making the code more self documenting, i.e.

int main(){

  auto DoThatOneThing = [&]{while(CheckCondition()){
    for(;;){
      if(!CheckOtherCondition())
        return;
      // do stuff...
    }
    // do stuff...
  }};

  DoThatOneThing();
  std::cout << "yep, broke out of it\n";
}
like image 188
Benjamin Lindley Avatar answered Oct 28 '22 21:10

Benjamin Lindley


Please don't do that in a project I'm managing. That's an awkward abuse of lambdas in my opinion.

Use a goto where a goto is useful.

like image 22
Johannes Schaub - litb Avatar answered Oct 28 '22 20:10

Johannes Schaub - litb