让我们考虑一下:
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
不是一个选项)。
有什么想法吗?
答案 0 :(得分:3)
一般情况下,这是少数情况之一,使用gotos通常被认为是正常的。但是,因为c ++ 11 我更喜欢使用立即调用的lambda 和return语句:
[&]{
switch(x)
{
case something:
{
for(something_else : some_container)
{
if(a_condition)
{
return ;
}
}
some_statements();
break;
}
}
}(); //<- directly invokes the lambda
一旦你有了这个,想想你是否想把整个块放到一个单独的命名函数中。
答案 1 :(得分:1)
goto版本还可以,但更好的替代方案可能是使用一个函数并在异常条件下从它返回:
*:focus {
border:3px solid black !important;
}
这里的优点是它允许您使用状态变量(对于错误代码等)。
另一种选择是异常处理。
答案 2 :(得分: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
,则立即调出true
。
是的,您可以使用自己的函数/ lambda来代替std::any_of
来模仿此模式
不,如果你的功能本身没有意义,那就不是一个好主意。{/ 1}}。
答案 3 :(得分: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; }
// ...
}