using STL to find all elements in a vector

前端 未结 7 656
时光取名叫无心
时光取名叫无心 2020-12-31 08:01

I have a collection of elements that I need to operate over, calling member functions on the collection:

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


        
相关标签:
7条回答
  • 2020-12-31 08:12

    For what its worth for_each_if is being considered as an eventual addition to boost. It isn't hard to implement your own.

    0 讨论(0)
  • 2020-12-31 08:16

    Boost Lambda makes this easy.

    #include <boost/lambda/lambda.hpp>
    #include <boost/lambda/bind.hpp>
    #include <boost/lambda/if.hpp>
    
    std::for_each( v.begin(), v.end(), 
                   if_( MyPred() )[ std::mem_fun(&MyType::myfunc) ] 
                 );
    

    You could even do away with defining MyPred(), if it is simple. This is where lambda really shines. E.g., if MyPred meant "is divisible by 2":

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


    Update: Doing this with the C++0x lambda syntax is also very nice (continuing with the predicate as modulo 2):

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

    At first glance this looks like a step backwards from boost::lambda syntax, however, it is better because more complex functor logic is trivial to implement with c++0x syntax... where anything very complicated in boost::lambda gets tricky quickly. Microsoft Visual Studio 2010 beta 2 currently implements this functionality.

    0 讨论(0)
  • 2020-12-31 08:16

    You can use Boost.Foreach:

    BOOST_FOREACH (vector<...>& x, v)
    {
        if (Check(x)
            DoStuff(x);
    }
    
    0 讨论(0)
  • 2020-12-31 08:17

    Lamda functions - the idea is to do something like this

    for_each(v.begin(), v.end(), [](MyType& x){ if (Check(x) DoSuff(x); })  
    

    Origial post here.

    0 讨论(0)
  • 2020-12-31 08:18
    std::vector<int> v, matches;
    std::vector<int>::iterator i = v.begin();
    MyPred my_pred;
    while(true) {
        i = std::find_if(i, v.end(), my_pred);
        if (i == v.end())
            break;
        matches.push_back(*i);
    }
    

    For the record, while I have seen an implementation where calling end() on a list was O(n), I haven't seen any STL implementations where calling end() on a vector was anything other than O(1) -- mainly because vectors are guaranteed to have random-access iterators.

    Even so, if you are worried about an inefficient end(), you can use this code:

    std::vector<int> v, matches;
    std::vector<int>::iterator i = v.begin(), end = v.end();
    MyPred my_pred;
    while(true) {
        i = std::find_if(i, v.end(), my_pred);
        if (i == end)
            break;
        matches.push_back(*i);
    }
    
    0 讨论(0)
  • 2020-12-31 08:32

    Is it ok to change the vector? You may want to look at the partition algorithm.
    Partition algorithm

    Another option would be to change your MyType::myfunc to either check the element, or to take a predicate as a parameter and use it to test the element it's operating on.

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