打破std :: for_each循环

Nav*_*een 26 c++ stl

使用std :: for_each算法时如何在满足某个条件时中断?

Ant*_*lov 21

你可以使用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
  });
Run Code Online (Sandbox Code Playgroud)

但是,这是一个浪费的解决方案(返回值并没有真正用于任何事情),你最好写自己的循环.

  • 真正有帮助的最佳答案 (2认同)

Joh*_*ing 14

您可以通过从仿函数中抛出异常来中断for_each().然而,这通常不是一个好主意,并且有其他选择.

您可以在您的仿函数中保留状态.如果你检测到'break'条件,只需在你的仿函数中设置一个标志,然后对于每个后续的迭代,只需返回而不做你的仿函数的事情.显然,这不会停止迭代,这对于大型集合来说可能是昂贵的,但它至少会阻止执行工作.

如果您的集合已经排序,您可以找到()要中断的元素,然后从begin()到返回的元素find()执行for_each.

最后,你可以实现一个for_each_if().这将再次不会停止迭代,但是如果谓词的计算结果为false,则不会评估您的函数.这里有两种风格for_each_xxx(),一种是取值而且如果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;
    };
Run Code Online (Sandbox Code Playgroud)


Căt*_*tiș 13

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

但是,这是一个黑客,所以你可以使用算法.

另一种方法是使用BOOST_FOREACH.


bay*_*yda 6

如果你想在条件不满足的情况下做一些动作,也许你需要改变算法std::find_if

  • 这是简单的方法.当你想停下来时,只需返回true. (2认同)

lot*_*har 5

正如其他人已经表明的那样,只有通过恕我直言混淆代码的变通方法才能实现。

所以我的建议是将 for_each 更改为常规的 for 循环。这将使其他人更容易看到您正在使用中断(甚至可能继续)。