当前位置:  开发笔记 > 编程语言 > 正文

使用STL查找向量中的所有元素

如何解决《使用STL查找向量中的所有元素》经验,为你挑选了3个好方法。

我有一组需要操作的元素,在集合上调用成员函数:

std::vector v;
... // vector is populated

对于没有参数调用函数,它非常简单:

std::for_each(v.begin(), v.end(), std::mem_fun(&MyType::myfunc));

如果我希望调用的函数有一个参数,则可以执行类似的操作.

我的问题是,如果满足某些条件,我想在向量中的元素上调用一个函数. std::find_if将迭代器返回到符合谓词条件的第一个元素.

std::vector::iterator it  = 
      std::find_if(v.begin(), v.end(), MyPred());

我希望找到符合谓词的所有元素并对它们进行操作.

我一直在研究STL算法的" find_all"或" do_if"等价物,或者我可以用现有的STL做这个(这样我只需要迭代一次),而不是自己滚动或只是做一个标准迭代使用for循环和比较.



1> paxos1977..:

Boost Lambda让这很容易.

#include 
#include 
#include 

std::for_each( v.begin(), v.end(), 
               if_( MyPred() )[ std::mem_fun(&MyType::myfunc) ] 
             );

如果它很简单,你甚至可以取消定义MyPred().这是lambda真正闪耀的地方.例如,如果MyPred意味着"可以被2整除":

std::for_each( v.begin(), v.end(), 
               if_( _1 % 2 == 0 )[ std::mem_fun( &MyType::myfunc ) ]
             );


更新: 使用C++ 0x lambda语法执行此操作也非常好(继续将谓词作为模2):

std::for_each( v.begin(), v.end(),
               [](MyType& mt ) mutable
               {
                 if( mt % 2 == 0)
                 { 
                   mt.myfunc(); 
                 }
               } );

乍一看,这看起来像是从boost :: lambda语法向后退一步,但是,它更好,因为使用c ++ 0x语法实现更复杂的functor逻辑很简单......在boost :: lambda中任何非常复杂的东西都会变得棘手很快.Microsoft Visual Studio 2010 beta 2目前实现此功能.



2> John Dibling..:

我写了一个for_each_if()和一个for_each_equal()我认为你正在寻找的东西.

for_each_if()使用谓词仿函数来评估相等性,并for_each_equal()获取任何类型的值并使用直接比较operator ==.在这两种情况下,传递的函数都会在通过相等性测试的每个元素上调用.

/* ---

    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;
    };



3> Marcin..:

改变矢量可以吗?您可能想要查看分区算法.
分区算法

另一个选择是更改您MyType::myfunc要么检查元素,要么将谓词作为参数并使用它来测试它正在操作的元素.

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有