2009-06-22 6 views
11

Disons que je hiérarchie comme ceci (Ceci est juste un programme de test S'il vous plaît ne pas pointer tout ce qui concerne les fuites de mémoire, destructor est pas etc virtuel.):Comment passer deux paramètres lors de l'utilisation de 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. 
} 

Comment puis-je appeler la méthode fun() qui prend deux arguments en utilisant le std :: for_each? Je pense que je dois utiliser std :: mem_fun probablement avec std :: bind2nd mais je ne suis pas capable de comprendre comment faire cela. Toute idée comment y parvenir? Je n'utilise pas de boost.

+1

Si vous n'utilisez pas boost, vous n'avez pas de tr1? –

Répondre

7

Vous pouvez créer votre propre foncteur comme ceci:

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

ou de l'utilisation boost :: bind comme ceci:

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

J'espérais que je pourrais éviter d'écrire un foncteur ... il me semble qu'il n'y a pas d'issue. N'est-ce pas? – Naveen

+0

Je ne sais pas s'il y a un moyen d'utiliser seulement stl puisque std :: mem_fun accepte au plus un argument. – Tobias

4

Vous ne pouvez pas faire cela avec les classeurs std. Vous pouvez bien sûr écrire votre propre foncteur.

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

Une autre façon de le faire serait d'utiliser des modèles. (S'il vous plaît me dire si c'est une mauvaise pratique, cependant!)

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

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

Ce serait bien si vous ne comptez pas l'appeler avec beaucoup de paramètres différents, car il générerait code pour toutes les combinaisons que vous avez fait.

+1

c'est intéressant .. Je n'ai jamais pensé à l'implémenter comme ça. – Naveen

+4

Mais cette solution ne fonctionne que si les paramètres N, N1 sont connus au moment de la compilation. Vous ne pouvez pas écrire std :: for_each (a.begin(), a.end(), Appliquer ); – Tobias

+0

Vous avez raison monsieur –

Questions connexes