2017-03-03 48 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; } 
    // ... 
}