tags:

views:

583

answers:

3

Lets say I have hierarchy like this (This is just a test program. Please do not point anything related to memory leaks, destructor is not virtual etc):

class I
{
public:
    virtual void fun(int n, int n1) = 0;
};

class A : public I
{
public:
    void fun(int n, int n1)
    {
     std::cout<<"A::fun():" <<n<<" and n1:" <<n1<<"\n";
    }
};

class B : public I
{
public:
    void fun(int n, int n1)
    {
     std::cout<<"B::fun():" <<n<<" and n1:" <<n1<<"\n";
    }
};


int  main()
{
    std::vector<I*> a;
    a.push_back(new A);
    a.push_back(new B);

    //I want to use std::for_each to call function fun with two arguments.
}

How do I call fun() method which takes two arguments using the std::for_each ? I think I have to use std::mem_fun probably with std::bind2nd but am not able to figure out how to do this. Any clue how to achieve this? I am not using boost.

+2  A: 

You can't do this with the std binders. You can of course write your own functor.

struct TwoArguments
{
   int one;
   int two;

   TwoArguments( int one, int two ) : one(one),two(two){
   }

   void operator()( I* i ) const {
       i->fun( one, two );
   }
};
TimW
+2  A: 

You could create your own functor like this:

class Apply
{
private:
  int arg1, arg2;

public:
  Apply(int n, int n1)
    : arg1(n), arg2(n1) 
  {}        

  void operator() (I* pI) const
  {
    pI->fun(arg1, arg2);
  }
};

int main ()
{
  // ...
  std::for_each(a.begin(), a.end(), Apply(n, n1));
}

or use boost::bind like this:

std::for_each(
  a.begin(),
  a.end(),
  boost::bind(&I::fun, _1, n, n1));
Tobias
I was hoping that I can avoid writing a functor..looks like there is no way out. Isn't it?
Naveen
I don't know if there is a way using only stl since a std::mem_fun accepts at most one argument.
Tobias
+1  A: 

Another way to do this would be to use templates. (Please tell me if it's a bad practice though!)

template<int N, int N1>
void Apply(I* i)
{
  i->fun(N, N1);
}

std::for_each(a.begin(), a.end(), Apply<firstParam, secondParam>);

That would be good if you don't intend to call it with a lot of different parameters since it would generate code for every combination you made.

Gab Royer
thats interesting.. I never thought about implementing it like this.
Naveen
But this solution only works if the parameters N, N1 are known at compile time. You cannot writestd::for_each(a.begin(), a.end(), Apply<getN(), getN1()>);
Tobias
You sir are right
Gab Royer