Question

J'essaie d'utiliser l'algorithme stl pour_each sans multiplier les modèles dans tout mon code. std :: for_each veut instancier la classe MyFunctor par valeur, mais ne le peut pas depuis son résumé. J'ai créé une classe d'adaptateur de foncteur qui fait passer un pointeur puis le neutralise le cas échéant.

Ma question:

La STL ou Boost a-t-elle déjà une telle classe d’adaptateur? Je ne veux pas avoir à réinventer la roue!

 struct MyFunctor  {
     virtual ~MyFunctor() {}
     virtual void operator()(int a) = 0; 
 }

 namespace {
     template<typename FunctorType, typename OperandType> struct
 FunctorAdapter
     {
         FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
         void operator()(OperandType& subject)
         {
             (*mFunctor)(subject);
         }

         FunctorType* mFunctor;
     }; }

 void applyToAll(MyFunctor &f) {
     FunctorHelper<MyFunctor, int> tmp(&f);
     std::for_each(myvector.begin(), myvector.end(), tmp); }

A bientôt,

Dave

Était-ce utile?

La solution

tr1 :: ref peut vous aider ici --- il est censé être un wrapper de référence afin que vous puissiez transmettre des objets normaux par référence à des objets de liaison ou de fonction (même des objets abstraits) en vous référant à des algorithmes standard.

// requires TR1 support from your compiler / standard library implementation
#include <functional>

void applyToAll(MyFunctor &f) {
    std::for_each(
        myvector.begin(), 
        myvector.end(), 
        std::tr1::ref(f) 
    ); 
}

Cependant, notez que les compilateurs sans decltype prennent en charge PEUVENT refuser de transmettre une référence à un type abstrait ... afin que ce code ne puisse pas être compilé tant que vous n'avez pas pris en charge C ++ 0x.

Autres conseils

Vous pouvez utiliser les adaptateurs de fonction (et leurs cales) à partir de fonctionnel .

#include <functional>

using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );

Si votre conteneur contient des pointeurs sur des objets, utilisez mem_fun_ptr , sinon utilisez mem_fun . A côté de ceux-ci, il y a des wrappers pour les fonctions membres qui prennent un argument: mem_fun1_ptr et mem_fun1 .

@Evan: vous pouvez en effet appeler la fonction membre avec le même argument pour chaque objet. Le premier argument des wrappers mem_fun1 est le pointeur this , le second est l'argument de la fonction membre:

for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );

Avec plus d'arguments, il devient plus lisible de créer une boucle vous-même ou de créer un foncteur personnalisé comportant des variables de membre const représentant les arguments.

Il semblerait que vous puissiez tirer parti de Boost :: Function .

Si je me souviens bien, c'est aussi une bibliothèque contenant uniquement un en-tête, il est donc facile de le faire fonctionner.

Pourquoi ne pas oublier l’habillage du pointeur du foncteur et utiliser à la place bind (functor_pointer, mem_fun1 (& MyFunctor :: operator ());  en tant que foncteur? De cette façon, vous n’aurez plus à vous soucier de la gestion de la copie.

Construire sur la réponse de @ xtofl, car le tableau contient les int et pas "this" pointeurs, je pense que la bonne incantation est

class MyClass
{
  virtual void process(int number) = 0;
};
MyClass *instance = ...;

for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );

La seule différence par rapport au code de @ xtofl est binder1st plutôt que binder2nd. binder2nd vous permet de transmettre le même numéro à plusieurs "ceci". pointeurs. binder1st vous permet de passer différents numéros à un "ceci". pointeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top