Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use std::foreach with parameters/modification

Tags:

I've found myself writing

for(int i=0;i<myvec.size();i++)
   myvec[i]->DoWhatever(param);

a lot, and I'd like to compress this into a foreach statement, but I'm not sure how to get param in there without going super-verbose. I've also got things like

for(int i=0;i<myvec.size();i++)
   if(myvec[i]->IsOK())
      myvec[i]->DoWhatever(param);

and I'd like to rewrite that guy too. Any thoughts?

Oh, also, for various reasons, I don't want to use boost.

like image 817
Jesse Beder Avatar asked Jan 24 '09 18:01

Jesse Beder


2 Answers

#include <vector>
#include <algorithm>
#include <functional>

class X
{
    public:
        void doWhat(int x) {}
        bool IsOK() const {return true;}
};
class CallWhatIfOk
{
    public:
        CallWhatIfOk(int p): param(p) {}

        void operator()(X& x) const
        {   if (x.IsOK())    {x.doWhat(param);}}
    private:
        int param;
};

int main()
{
    std::vector<X>      myVec;

    std::for_each(  myVec.begin(),
                    myVec.end(),
                    std::bind2nd(std::mem_fun_ref(&X::doWhat),4)
                 );


    std::for_each(  myVec.begin(),
                    myVec.end(),
                    CallWhatIfOk(4)
                 );
}
like image 124
Martin York Avatar answered Sep 29 '22 12:09

Martin York


Oh, also, for various reasons, I don't want to use boost.

Valid decision, but most likely the wrong one. Consider Boost as an extension to the STL. C++ is a library-driven language. If you don't take this into account, your code will be qualitatively inferior.

While std::for_each can be used here, the absence of lambda expressions in C++ until C++0x makes this tedious. I advocate using Boost.ForEach! It makes this much easier:

foreach (yourtype x, yourvec)
    if (x.IsOK())
        x.Whatever();
like image 23
Konrad Rudolph Avatar answered Sep 29 '22 11:09

Konrad Rudolph