Is there an equivalent to the “for … else” Python loop in C++?

前端 未结 14 2035
野的像风
野的像风 2021-01-31 01:21

Python has an interesting for statement which lets you specify an else clause.

In a construct like this one:

for i in foo:
  if         


        
相关标签:
14条回答
  • 2021-01-31 02:00

    I would accomplish this with a simple helper variable:

    #include <stdio.h>
    #include <stdbool.h>
    
    int main()
    
    {
        bool b;
        printf("Numbers which are multiples of 7:\n");
    
        for (int i=8; b=(i<12); i++)
        {
            if (i%7==0)
            {
                printf("%d", i);
                break;
            }
        }
        if (!b)
        {
            printf("no numbers found\n");
        }
        return 0;
    }
    

    This way, you need to implement the condition (in the above examplei<12) only at one place.

    0 讨论(0)
  • 2021-01-31 02:01

    This is my rough implementation in C++:

    bool other = true;
    for (int i = 0; i > foo; i++) {
         if (bar[i] == 7) {
              other = false;
              break;
         }
    } if(other)
         baz();
    
    0 讨论(0)
  • 2021-01-31 02:01

    Something like:

    auto it = foo.begin(), end = foo.end();
    while ( it != end && ! bar( *it ) ) {
        ++ it;
    }
    if ( it != foo.end() ) {
        baz();
    }
    

    should do the trick, and it avoids the unstructured break.

    0 讨论(0)
  • 2021-01-31 02:02

    You could use a lambda function for this:

    [&](){
      for (auto i : foo) {
        if (bar(i)) {
          // early return, to skip the "else:" section.
          return;
        }
      }
      // foo is exhausted, with no item satisfying bar(). i.e., "else:"
      baz();
    }();
    

    This should behave exactly like Python's "for..else", and it has some advantages over the other solutions:

    • It's a true drop-in replacement for "for..else": the "for" section can have side effects (unlike none_of, whose predicate must not modify its argument), and it has access to the outer scope.
    • It's more readable than defining a special macro.
    • It doesn't require any special flag variables.

    But... I'd use the clunky flag variable, myself.

    0 讨论(0)
  • 2021-01-31 02:04

    I am not aware of an elegant way to accomplish this in C/C++ (not involving a flag variable). The suggested other options are much more horrible than that...

    To answer @Kerrek SB about real life usages, I found a few in my code (simplified snippets)

    Example 1: typical find/fail

    for item in elements:
        if condition(item):
            do_stuff(item)
            break
    else: #for else
        raise Exception("No valid item in elements")
    

    Example 2: limited number of attempts

    for retrynum in range(max_retries):
        try:
            attempt_operation()
        except SomeException:
            continue
        else:
            break
    else: #for else
        raise Exception("Operation failed {} times".format(max_retries))
    
    0 讨论(0)
  • 2021-01-31 02:05

    I came here because I had the same question, in C though. The best thing I came out with is

    bool notTerminated = true;
    for (int i = 0; i < 50 || (notTerminated = false); i++)
        if (bar(i))
            break;
    if (! notTerminated)
        baz();
    

    Explanation: the (notTerminated = false) is an assignment that will always return the false value, it will never affect the condition and will be evaluated iif the condition if true.

    0 讨论(0)
提交回复
热议问题