2017-03-03 41 views
2

让我们考虑:如何从循环跳出开关C++里面

switch(x) 
{ 
case something: 
    { 
     for(something_else : some_container) 
     { 
      if(a_condition) 
      { 
      // BREAK OUT OF THE SWITCH 
      } 
     } 
     some_statements(); 
     break; 
     } 
} 

我如何从循环这是一个switch语句中,因为我不希望运行some_statements();最优雅的方式逃脱。

当然,一个很好地goto将很好地解决这个问题,但解决方案可以考虑什么,但优雅:

switch(x) 
{ 
case something: 
    { 
     for(something_else : some_container) 
     { 
      if(a_condition) 
      { 
        goto escape_route; 
      } 
     } 
     some_statements(); 
     break; 
     } 
} 
escape_route: 
// Hurrah, freedom 

,也是一个标志将解决这个问题:

switch(x) 
{ 
case something: 
    { 
     bool flag = true; 
     for(something_else : some_container) 
     { 
      if(a_condition) 
      { 
        flag = false; 
        break; 
      } 
     } 
     if(flag) 
     { 
      some_statements(); 
     } 
     break; 
     } 
} 

但是,让我们只是说,我正在寻找针对这个问题的其他解决方案(请注意:交换机之后有更多语句,return ing不是选项)。

任何想法?

+0

你能否详细说明有关切换后的其他语句? –

+3

'goto'看起来不错。不要反套 - 你只会让它更加纠结。 – Quentin

+0

为什么你认为'goto'不是“优雅”?它清晰,简单,干净 - 几乎是优雅的**定义。 –

回答

3

一般来说,这是少数情况下,使用gotos通常被认为是好的之一。然而,由于C++ 11 我更喜欢使用立即调用拉姆达和return语句:

[&]{ 
    switch(x) 
    { 
    case something: 
     { 
      for(something_else : some_container) 
      { 
       if(a_condition) 
       { 
        return ; 
       } 
      } 
      some_statements(); 
      break; 
     } 
    } 
}(); //<- directly invokes the lambda 

一旦你有这样的,想想如果你可能想要把整个街区到一个单独的命名函数。

0

goto看起来没问题。不要反套 - 你只会让它更加纠结。

虽然这是一般情况。您的具体使用看起来像可以折叠到一个不错的电话<algorithm>

switch(x) 
{ 
case something: 
    { 
     if(std::any_of(
      begin(some_container), 
      end(some_container), 
      [](auto &&e) { return a_condition(e); } 
     )) 
      break; 

     some_statements(); 
     break; 
    } 
} 

注意,这个调用一个函数,它不早回来,并立即break s出,如果它返回true
是的,你可以用你自己的函数/ lambda代替std::any_of来模仿这个模式。
不,这不是一个好主意,如果你的功能自己没有意义,就像std::any_of那样。

1

其中goto版本确定,但一个更好的选择可能是使用的函数,在一个特殊的情况,从它返回:

status_t func (void) 
{ 
    status_t status = default_value; 

    switch(x) 
    { 
    case something: 
    { 
     for(something_else : some_container) 
     { 
     if(a_condition) 
     { 
      return status; 
     } 
     } 
     some_statements(); 
     break; 
    } 
    } 

    return status; 
} 

这里的好处是,它可以让你用一个状态变量(错误代码等)。

另一种选择是异常处理。

+3

作为流量控制的异常处理?请不要这样做...... – Quentin

+0

@Quentin取决于“a_condition”的含义,不是吗? – Lundin

+0

它的确如此,但我希望OP提及它,如果它实际上是错误处理而不是程序逻辑。 – Quentin

0

我可能会分裂功能为子功能,消除内环路您休息的需要,是这样的:

void foo(/*...*/) 
{ 
    for (auto something_else : some_container) { 
     if (a_condition) { 
      return; 
     } 
    } 
    some_statements(); 
} 

然后

switch (x) 
{ 
    case something: { foo (/*...*/); break; } 
    case something2: { foo2(/*...*/); break; } 
    case something3: { foo3(/*...*/); break; } 
    // ... 
}