代码之家  ›  专栏  ›  技术社区  ›  Naveen

断开std::for ou each loop

  •  26
  • Naveen  · 技术社区  · 15 年前

    当使用std::for_每个算法时,当满足某个条件时,如何中断?

    7 回复  |  直到 12 年前
        1
  •  13
  •   Cătălin Pitiș    15 年前

    您可以使用find_if算法,它将停止并返回迭代器,其中应用于迭代器元素的谓词条件返回true。因此,应该更改谓词以返回布尔值作为Continue/Break条件。

    然而,这是一个黑客,所以你可以使用算法。

    另一种方法是使用Boost-ForEach。

        2
  •  20
  •   Anton Belov    12 年前

    您可以使用std::any_of(或std::all_of或std::none_of),例如:

    std::vector<int> a;
    // ...     
    std::all_of(a.begin(), a.end(), [&](int val) { 
      // return false if you want to break, true otherwise
      });
    

    然而,这是一个浪费的解决方案(返回值实际上不用于任何事情),最好编写自己的循环。

        3
  •  14
  •   John Dibling    15 年前

    通过从函数中抛出异常,可以从for each()中断。然而,这通常不是一个好主意,而且还有其他选择。

    您可以在函数中保留状态。如果检测到“中断”条件,只需在函数中设置一个标志,然后对于每个后续迭代,只需返回而不执行函数的操作。显然,这不会停止迭代,这对于大型集合来说可能很昂贵,但它至少会停止正在执行的工作。

    如果对集合进行了排序,则可以查找()要在其处中断的元素,然后从begin()到返回的element find()对每个元素执行此操作。

    最后,您可以实现 for_each_if() . 这不会再次停止迭代,但不会计算在谓词计算为false时执行该操作的函数。这有两种口味 for_each_xxx() ,一个接受一个值并执行wk if operator==()的计算结果为true,另一个接受两个函数;一个执行比较ala find_if(),另一个执行比较运算符的计算结果为true时的工作。

    /* ---
    
        For each
        25.1.1
    
            template< class InputIterator, class Function, class T>
                Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f)
    
            template< class InputIterator, class Function, class Predicate >
                Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f)
    
        Requires:   
    
            T is of type EqualityComparable (20.1.1) 
    
        Effects:    
    
             Applies f to each dereferenced iterator i in the range [first, last) where one of the following conditions hold:
    
                1:  *i == value
                2:  pred(*i) != false
    
        Returns:    
    
            f
    
        Complexity: 
    
            At most last - first applications of f
    
        --- */
    
        template< class InputIterator, class Function, class Predicate >
        Function for_each_if(InputIterator first, 
                             InputIterator last, 
                             Predicate pred, 
                             Function f)
        {
            for( ; first != last; ++first)
            {
                if( pred(*first) )
                    f(*first);
            }
            return f;
        };
    
        template< class InputIterator, class Function, class T>
        Function for_each_equal(InputIterator first, 
                                InputIterator last, 
                                const T& value, 
                                Function f)
        {
            for( ; first != last; ++first)
            {
                if( *first == value )
                    f(*first);
            }
            return f;
        };
    
        4
  •  6
  •   bayda    15 年前

    如果您想在条件不满足的情况下执行一些操作,可能需要对类似的内容执行更改算法 std::find_if ?

        5
  •  4
  •   lothar    15 年前

    正如其他人所展示的,只有在解决方法使代码变得模糊的情况下才能实现。

    因此,我的建议是将for-each改为正则for循环。这将使您使用break的其他人更容易看到它(甚至可能继续)。

        6
  •  2
  •   Dave Van den Eynde    15 年前

    除非抛出异常,否则无法执行此操作,这不是一个好主意,因为不执行带有异常的流控制。

    更新:很明显Boost有一个for-each-u 可以 救命,但你没有使用助推器。

        7
  •  0
  •   Charlie Martin    15 年前

    你提出了一个例外。这是否是一个好主意是一个风格问题,佩斯@丹,但可能更多的是你的设计问题。for_每个函数都是一种函数式编程风格,它隐式地假设您的函数可以在整个集合中统一应用。所以,如果你 需要打破,这可能是一个不寻常的情况,因此值得一个例外。

    另一个解决方案,以及一个更“实用”的解决方案,是编写您的函数,这样如果它不应该对某些应用程序产生影响,那么就编写它来不产生任何影响。例如,如果你有一个求和函数,让它在你“破坏”的情况下加0。