2009-06-22 15 views
11

Digamos que tengo jerarquía como esto (Esto es sólo un programa de prueba Por favor, no apunte todo lo relacionado con las pérdidas de memoria, destructor no es virtual, etc.):¿Cómo pasar dos parámetros al usar std :: mem_fun?

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

¿Cómo método de diversión() que llamo el cual toma dos argumentos usando std :: for_each? Creo que tengo que usar std :: mem_fun probablemente con std :: bind2nd pero no soy capaz de descubrir cómo hacerlo. ¿Alguna pista de cómo lograr esto? No estoy usando boost.

+1

¿No usar boost significa que no tiene tr1? –

Respuesta

7

Usted puede crear su propia funtor como esto:

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

o uso boost :: bind así:

std::for_each(
    a.begin(), 
    a.end(), 
    boost::bind(&I::fun, _1, n, n1)); 
+0

Tenía la esperanza de poder evitar escribir un functor ... parece que no hay escapatoria. ¿No es así? – Naveen

+0

No sé si hay una forma de usar stl solo, ya que std :: mem_fun acepta como máximo un argumento. – Tobias

4

No puede hacer esto con los encuadernadores estándar. Por supuesto, puede escribir su propio 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); 
    } 
}; 
1

Otra manera de hacer esto sería el uso de plantillas. (Por favor, dígame si es una mala práctica, sin embargo!)

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

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

que sería bueno si usted no tiene intención de llamarlo con una gran cantidad de diferentes parámetros, ya que generaría código para cada combinación que ha realizado.

+1

eso es interesante ... Nunca pensé en implementarlo así. – Naveen

+4

Pero esta solución solo funciona si los parámetros N, N1 son conocidos en tiempo de compilación. No puede escribir std :: for_each (a.begin(), a.end(), Apply ); – Tobias

+0

Usted señor tiene razón –

Cuestiones relacionadas