Frage

Ich versuche stl Algorithmus for_each zu verwenden, ohne Vorlagen in meinem Code wuchernden. std :: for_each will MyFunctor Klasse von Wert instanziiert, aber es kann nicht da sein abstrakt. Ich habe eine Funktor-Adapter-Klasse erstellt, die einen Zeiger läuft um und derefernces es dann, wenn angemessen.

Meine Frage:

Ist die STL oder bereits einen solchen Adapter Klasse boost haben? Ich will nicht zu haben, das Rad neu zu erfinden!

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

Cheers,

Dave

War es hilfreich?

Lösung

tr1 :: ref Sie können hier helfen --- es soll eine Referenz-Wrapper sein, so dass Sie normale Objekte durch Verweis übergeben kann binden oder Funktionsobjekte (auch abstrakt sind) unter Bezugnahme auf Standard-Algorithmen.

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

Beachten Sie jedoch, dass ohne decltype Unterstützung Compiler MAY ablehnen gibt einen Verweis auf eine abstrakte Art ... so kann dieser Code nicht kompiliert werden, bis Sie C erhalten ++ 0x-Support.

Andere Tipps

Sie können die Funktionsadapter verwenden (und die Beilagen) aus functional.

#include <functional>

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

Wenn Ihr Behälter enthält Zeiger zu Objekten, die Verwendung mem_fun_ptr, sonst Verwendung mem_fun. Neben diesen gibt es Wrapper für Member-Funktionen, die mit 1 Argumente: mem_fun1_ptr und mem_fun1

.

@ Evan: in der Tat, können Sie für jedes Objekt die Member-Funktion mit dem gleichen Argument nennen. Das erste Argument der mem_fun1 Umhüllungen ist der this Zeiger, die zweite ist die Elementfunktion Argument:

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

Mit mehr Argumente, es wird besser lesbar eine Schleife selbst zu erstellen oder einen benutzerdefinierten Funktors erstellen, die const Membervariablen hat die Argumente darstellen.

Klingt wie Sie von boost :: Funktion .

Wenn ich mich richtig erinnere, dann ist es ein Header nur zu Bibliothek, so dass es einfach ist, es mit ihm in Gang zu bringen.

Was ist mit all der Verhüllung des Funktors Zeigers zu vergessen und stattdessen bind(functor_pointer,mem_fun1(&MyFunctor::operator());  als Funktors? auf diese Weise, die Sie nicht über die Verwaltung die Kopie in irgendeiner Weise oder Form zu kümmern.

Aufbauend auf @ xtofl Antwort, da das Array int ist und nicht „diese“ Zeiger, ich glaube, die richtige Beschwörung ist

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

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

Der einzige Unterschied im Vergleich @ xtofl Code ist binder1st statt binder2nd. binder2nd können Sie teh gleiche Anzahl an verschiedenen „dieses“ Zeiger zu übergeben. binder1st können Sie verschiedene Zahlen ein „dieser“ Zeiger zu übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top