Verständnisfrage zu Funktor



  • Salve,
    ich verstehe offensichtlich die Funktionsweise eines Funktors nicht ganz. Um mein Problem zu verdeutlichen, habe ich ein kleines Beispiel:

    #include <iostream>
    #include <vector>
    #include <sstream>
    
    using namespace std;
    
    class FindIt
    {
    	public:
    		FindIt(int _i) : i(_i), anz(0){}
    		int getFound(){return anz;}
    
    		bool operator()(const int &cmp) {++anz; cout << "anz = " << anz << endl; return i == cmp;}
    
    	private:
    		int i;
    		int anz;
    };
    
    int main(int argc, char **argv)
    {
    	if(argc < 2)
    		return 1;
    
    	stringstream ss;
    	ss << argv[1];
    
    	int suchint;
    	ss >> suchint;
    
    	if(ss.fail())
    		return 1;
    
    	vector<int> ivec;
    
    	ivec.push_back(10);
    	ivec.push_back(12);
    	ivec.push_back(8);
    
    	vector<int>::iterator it;
    
    	FindIt fi(suchint);
    	it = find_if(ivec.begin(), ivec.end(), fi);
    
    	cout << "Gefunden an " << fi.getFound() << ". " << "Stelle\n";
    
    }
    

    Wenn man das Programm ausführt und als Parameter einen der Werte im Vektor mitgibt, sieht man, daß es entsprechend oft durch die operator() - Methode läuft und die Anzahl der Durchläufe mitgezählt wird.
    Nachdem das richtige Element gefunden wurde, kann ich die Anzahl der Durchläufe aber nicht mehr erkennen, anz steht wieder auf 0.
    In meiner Anwendung habe ich einen Vektor mit komplexen Elementen und will mit den Objekten, die die Suchbedingung nicht erfüllen, Berechnungen durchführen und danach das Ergebnis abholen, das aber funktioniert so natürlich nicht, wenn der Wert verloren geht.

    Warum ist das so?
    Wenn ich anz in main definiere und dem Funktor nur eine Referenz darauf mitgebe, klappt das, aber das gefällt mir nicht so richtig.



  • std::find übernimmt den Funktor per Value. D.h. dein Funktor wird in std::find_if "kopiert". Dann wird die Kopie geändert und dein Original bleibt erhalten.

    Abhilfte kannst du zB so schaffen:

    Functor f;
    std::find_if(.. , .. , boost::ref(f));
    


  • Belli schrieb:

    In meiner Anwendung habe ich einen Vektor mit komplexen Elementen und will mit den Objekten, die die Suchbedingung nicht erfüllen, Berechnungen durchführen und danach das Ergebnis abholen, das aber funktioniert so natürlich nicht, wenn der Wert verloren geht.

    Eventuell wird's aber auch weniger und verständlicherer Code, wenn du das in eine ordinäre Schleife packst.

    Für dein Beispiel mit dem Bestimmen der Anzahl würde ich http://cplusplus.com/reference/algorithm/count_if/]count_if nehmen.



  • Naja, in meiner Anwendung muß ich eine Liste splitten. Via find_if finde ich die richtige Position. Ich muß dann aus der neu zu bildenden Liste eine Summe aus den Membern ermitteln. Da dachte ich, es bietet sich an, daß gleich im Funktor erledigen zu lassen.
    Im Moment mache ich das halt so, daß ich dem Funktor eine Referenz übergebe, in die ich dann summieren lasse. Das funktioniert erst mal.


Log in to reply