如何从循环C ++中的循环中脱颖而出

时间:2017-03-03 11:52:18

标签: c++ loops switch-statement break

让我们考虑一下:

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不是一个选项)。

有什么想法吗?

4 个答案:

答案 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; }
    // ...
}