STL Problem



  • Ich hab da mal ein Problem:

    Gegeben (rudimentär, aus dem Kopf wiedergegeben):

    class Obj
    
    vector<Obj> contObj;
    
    class Filter
    {
    public:
       bool applyTo(Obj const &); // kann auch bool operator()(Obj const &) gewesen sein...
    }
    

    Nun soll der Vector gefiltert werden:

    contObj.erase(remove_if(contObj.begin(), contObj.end(), pred), contObj.end());
    

    Wie muss nun pred aussehen? Irgendwie steh ich da auf dem Schlauch....
    Spendiere ich Obj ein

    bool applyFilter(Filter const &)
    

    dann ginge es ja mit

    Filter filter;
    ...
    mem_fun_ref(bind2nd(&Obj::applyFilter, filter))
    

    Das ist aber in meinen Augen OO-technisch "durch die Brust ins Auge", schliesslich filtert ja Filter die Obj



  • Das Prädikat muß entweder eine (statische Klassen-)Funktion oder aber ein Funktor (Funktionsobjekt) sein, z.B.

    bool /*Filter::*/applyFilter(const Obj &obj)
    {
      return obj. /* ... */;
    }
    
    //Aufruf:
    remove_if(contObj.begin(), contObj.end(), /*&Filter::*/applyFilter);
    
    // oder
    
    struct ApplyFilter
    {
      bool operator ()(const Obj &obj) const
      {
         return obj./* ... */;
      }
    };
    
    //Aufruf:
    remove_if(contObj.begin(), contObj.end(), ApplyFilter());
    

    Der Vorteil beim Funktor ist, daß du dort noch einen Konstruktor mit Parametern erzeugen kannst, falls du z.B. noch eine Konstante als Vergleichswert übergeben willst.


  • Mod

    bind1st statt bind2nd



  • Th schrieb:

    Das Prädikat muß entweder eine (statische Klassen-)Funktion oder aber ein Funktor (Funktionsobjekt) sein, z.B.

    bool /*Filter::*/applyFilter(const Obj &obj)
    {
      return obj. /* ... */;
    }
    
    //Aufruf:
    remove_if(contObj.begin(), contObj.end(), /*&Filter::*/applyFilter);
    
    // oder
    
    struct ApplyFilter
    {
      bool operator ()(const Obj &obj) const
      {
         return obj./* ... */;
      }
    };
    
    //Aufruf:
    remove_if(contObj.begin(), contObj.end(), ApplyFilter());
    

    Der Vorteil beim Funktor ist, daß du dort noch einen Konstruktor mit Parametern erzeugen kannst, falls du z.B. noch eine Konstante als Vergleichswert übergeben willst.

    Ja, das mit dem Funktor ist mir bekannt, hab ich schon mehrfach so benutzt. Das Problem ist nur, dass es eben nicht nur einen Filter gibt, sondern deren unterschiedliche, die per Filter * aus einer FilterFactory kommen.



  • camper schrieb:

    bind1st statt bind2nd

    Wie meinst Du das genau?



  • Na dann dürften doch die STL-Funktionsadapter der richtige Weg sein - du mußt sie nur in der richtigen Reihenfolge anwenden:

    bool Filter::apply(const Obj& ob)
    {
      return obj./*...*/;
    }
    
    reomove_if(...,bind1st(mem_fun_ref(&Filter::apply),filter));
    

    (wobei es eventuell eleganter wäre, wenn deine Filter-Klasse den op() selbst überlädt)



  • CStoll schrieb:

    Na dann dürften doch die STL-Funktionsadapter der richtige Weg sein - du mußt sie nur in der richtigen Reihenfolge anwenden:

    bool Filter::apply(const Obj& ob)
    {
      return obj./*...*/;
    }
    
    reomove_if(...,bind1st(mem_fun_ref(&Filter::apply),filter));
    

    (wobei es eventuell eleganter wäre, wenn deine Filter-Klasse den op() selbst überlädt)

    Danke, das funktioniert jetzt soweit. Und ich hab das auch auf operator() umgestellt, das ist mir persönlich nämlich auch lieber 🙂


Anmelden zum Antworten