Problem mit Funktionsobjekten



  • Hi,

    #include <iostream>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    void myprint(int i, int val) {
        if (val > i)
            cout << val << endl;
    }
    
    int main() {
        list<int> li;
        for (int i = 0; i < 10; i++)
            li.push_back(i);
    
        // Hier soll für jedes Element aus li
        // die Funktion myprint() mit 5 als ersten Parameter aufgerufen werden
        for_each(li.begin(), li.end(), &myprint(5))
    };
    

    Wie gehts wirklich?

    Ich will eigentlich keine tausend Funktionen definieren, die alle myprint1() , myprint2() , usw heißen...



  • Funktionen bieten dafür zu wenig Flexibilität. Hier sind Funktionsobjekte (Funktoren) angebracht. Das sind Klassen, die den operator() überladen. Als Konstruktorargumente können sie zusätzliche Bedingungen nehmen.

    Der Funktor könnte zum Beispiel so aussehen:

    struct PrintFunctor
    { 
    	PrintFunctor(int Limit)
    	: MyLimit(Limit)
    	{
    	}
    
    	void operator() (int Value)
    	{
    		if (Value > MyLimit)
    			std::cout << Value << std::endl; 
    	}
    
    	int MyLimit;
    };
    

    Und in der Anwendung:

    std::for_each(List.begin(), List.end(), PrintFunctor(5));
    




  • super danke 🙂



  • zu spät



  • #include <list>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    void printif(int greater, int val) {
    	if (greater > val)
    		cout << val << " ";
    }
    
    int main () {
    	list<int> li;
    	for (unsigned int i = 0; i < 10; i++)
    		li.push_back(i);
    
    	std::for_each(li.begin(), li.end(), bind1st(printif(), 5));
    }
    

    Ausgabe:

    Fehler 1 error C2660: 'printif': Funktion akzeptiert keine 0 Argumente c:\test\test\base.cpp 17

    was mache ich falsch?



  • Du musst die Funktion selber übergeben, und nicht aufrufen. Also die Klammern weglassen...



  • #include <list>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    void printif(int greater, int val) {
    	if (greater > val)
    		cout << val << " ";
    }
    
    int main () {
    	list<int> li;
    	for (unsigned int i = 0; i < 10; i++)
    		li.push_back(i);
    
    	std::for_each(li.begin(), li.end(), bind1st(printif, 5));
    }
    
    Fehler	1	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	261
    Fehler	2	error C2039: 'second_argument_type': Ist kein Element von '`global namespace''	c:\program files\microsoft visual studio 8\vc\include\functional	261
    Fehler	3	error C2146: Syntaxfehler: Fehlendes ',' vor Bezeichner 'second_argument_type'	c:\program files\microsoft visual studio 8\vc\include\functional	261
    Fehler	4	error C2065: 'second_argument_type': nichtdeklarierter Bezeichner	c:\program files\microsoft visual studio 8\vc\include\functional	261
    Fehler	5	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	262
    Fehler	6	error C2039: 'result_type': Ist kein Element von '`global namespace''	c:\program files\microsoft visual studio 8\vc\include\functional	262
    Fehler	7	error C2146: Syntaxfehler: Fehlendes ',' vor Bezeichner 'result_type'	c:\program files\microsoft visual studio 8\vc\include\functional	262
    Fehler	8	error C2065: 'result_type': nichtdeklarierter Bezeichner	c:\program files\microsoft visual studio 8\vc\include\functional	262
    Fehler	9	error C2955: "std::unary_function": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.	c:\program files\microsoft visual studio 8\vc\include\functional	263
    Fehler	10	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	265
    Fehler	11	error C2143: Syntaxfehler: Es fehlt ',' vor '`global namespace'::second_argument_type'	c:\program files\microsoft visual studio 8\vc\include\functional	265
    Fehler	12	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	266
    Fehler	13	error C2143: Syntaxfehler: Es fehlt ',' vor '`global namespace'::result_type'	c:\program files\microsoft visual studio 8\vc\include\functional	266
    Fehler	14	error C2955: "std::unary_function": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.	c:\program files\microsoft visual studio 8\vc\include\functional	267
    Fehler	15	error C2955: "std::unary_function": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.	c:\program files\microsoft visual studio 8\vc\include\functional	268
    Fehler	16	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	270
    Fehler	17	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	270
    Fehler	18	error C2039: 'first_argument_type': Ist kein Element von '`global namespace''	c:\program files\microsoft visual studio 8\vc\include\functional	270
    Fehler	19	error C2143: Syntaxfehler: Es fehlt ',' vor '&'	c:\program files\microsoft visual studio 8\vc\include\functional	270
    Fehler	20	error C2825: "_Fn2": Muss eine Klasse oder ein Namespace sein, wenn gefolgt von "::".	c:\program files\microsoft visual studio 8\vc\include\functional	288
    Fehler	21	error C2039: 'first_argument_type': Ist kein Element von '`global namespace''	c:\program files\microsoft visual studio 8\vc\include\functional	288
    Fehler	22	error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'value'	c:\program files\microsoft visual studio 8\vc\include\functional	288
    Fehler	23	error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	c:\program files\microsoft visual studio 8\vc\include\functional	288
    Fehler	24	error C2664: 'std::for_each': Konvertierung des Parameters 3 von 'std::binder1st<_Fn2>' in 'std::binder1st<_Fn2>' nicht möglich	c:\test\test\base.cpp	17
    


  • Bei Funktionen musst du einen Umweg über ptr_fun machen:

    std::for_each(li.begin(), li.end(), bind2nd (ptr_fun (&printif),5) );
    

    bind2nd braucht noch Informationen über die Typen, welche bei einer Funktion natürlich nicht ohne weiteres extrahiert werden können.


Anmelden zum Antworten