这是lambda表达式的有效(ab)使用吗?

时间:2011-05-20 21:21:20

标签: c++ lambda c++11 break nested-loops

就像我们都知道的那样,如果没有外部循环,从嵌套循环中break并不容易:

虽然,你必须承认,所有这些都有点笨拙。特别是函数版本缺少,因为缺少调用循环的上下文,因为您需要将循环中所需的所有内容作为参数传递。
另外,每个嵌套循环的第二个变得更糟 所以,我个人仍然认为goto版本是最干净的。


现在,考虑所有C ++ 0x和东西,第三个选项带给我这个想法利用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";
}

Example at Ideone.

这允许第三个选项提供的简单return的语义美,同时不会遇到上下文问题并且(几乎)像goto版本一样干净。它比任何上述选项都更短(以字符为单位)。


现在,我已经学会了在找到语言的美妙(ab)使用后保持喜悦,因为几乎总有一些缺点。这个有什么吗?或者甚至有更好的方法解决这个问题?

4 个答案:

答案 0 :(得分:16)

请不要在我管理的项目中这样做。在我看来,这是对lambdas的尴尬滥用。

使用goto goto有用的地方。{/ p>

答案 1 :(得分:4)

在我看来完全有效。虽然我更喜欢给我的名字分配,使代码更自我记录,即

int main(){

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

  DoThatOneThing();
  std::cout << "yep, broke out of it\n";
}

答案 2 :(得分:4)

以何种方式改进

void frgleTheBrgls()
{
  while(CheckCondition()) {
    for(;;) {
      if(!CheckOtherCondition())
        return;
      // do stuff...
    }
    // do stuff...
  }
}

int main()
{
  frgleTheBrgls();
  std::cout << "yep, broke out of it\n";
}

这是众所周知的(函数,你知道,如在BASIC中),更清楚(算法有一个很好的名称解释它的作用),并且与你的完全相同。

  

特别是函数版本缺少,因为调用循环时缺少上下文,因为您需要将循环中所需的所有内容作为参数传递。

我认为这是一个优势。你可以确切地看到褶皱brgls需要什么。编程时的明显性往往是一件好事。

答案 3 :(得分:1)

您提出的语法有一个缺点:您不能有超过2个嵌套循环。 'goto'语法允许这样:

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