Funktionspointer und std::tr1::function
-
Hallo,
Ich habe zwei Fragen zu Funktionspointern:Funktionspointer auf Memberfunktionen sind grundsätzlich möglich, jedoch ist der Aufruf einer solchen Funktion anders. Ist es möglich, in einer queue von Funktionspointern (std::queue<void (*)(std::ifstream)>) sowohl Pointer auf normale Funktionen als auch Pointer auf Memberfunktionen zu speichern und aufzurufen?
es gibt im TR1 das Template function. Ist dies einfach "modernerer" Funktionspointer (d.h. kann diese ersetzen) oder etwas völlig anderes? Ist dieses template möglicherweise in Bezug auf meine erste Frage hilfreich?
Danke schon im Voraus!
mfg
mr x
-
Zu 1:
So einfach geht das nicht. Ich weiß jetzt nicht ob es überhaupt geht, habe mich damit noch nicht beschäftigt. Wichtig ist für den Aufruf nicht-statischer Memberfunktionen, das du den this Zeiger benötigst. Ohne den geht nichts. Statische Memberfunktionen könntest du wahrscheinlich irgendwie umbiegen.
-
So einfach geht das nicht.
Das habe ich mir schon gedacht...

Statische Memberfunktionen könntest du wahrscheinlich irgendwie umbiegen.
Die dürften kein Problem sein, da sie ja nicht auf ein bestimmtes Objekt der Klasse bezogen sind. Leider ist die Funktion bei mir nicht statisch.
-
Wie gesagt, bei nicht-statischen Memberfunktionen benötigst du den this-Zeiger, ansonsten weiß man ja nicht für welches Objekt die Funktion ausgeführt werden soll.
-
Aber durch den this-Zeiger können sie allerdings nicht mehr mit normalen Funktionspointern gemischt werden (Aufruf der Funktion, auf den der Pointer zeigt und Deklaration muss gleich sein).
Meine Frage zielte mehr darauf ab, ob es vielleicht Zeiger auf Memberfunktionen bezogen auf ein festgelegtes Objekt gibt.
-
Hier ist ein kleines Beispiel, wie du Member- und freie Funktionen mit std::function unter einen Hut bringst:
#include <iostream> #include <tr1/functional> typedef std::tr1::function<void(int)> my_func_type; // dein funktionstyp struct test { void member_func(int v) { std::cout << "member_func: " << v << std::endl; } }; void free_func(int v) { std::cout << "free_func: " << v << std::endl; } int main() { // zeiger auf member function test t; my_func_type func1 = std::tr1::bind(&test::member_func, t, std::tr1::placeholders::_1); // zeiger auf freie funktion my_func_type func2 = std::tr1::bind(&free_func, std::tr1::placeholders::_1); // aufruf funktioniert für beide gleich func1(23); func2(42); }
-
Danke!
Das funktioniert und hat zugleich meine Frage nach std::tr1::function geklärt

-
Noch eine kleine Frage:
Was bedeutet "std::tr1::placeholders::_1"?
-
Das
_1repräsentiert das erste Argument.bind()erzeugt einen Funktor, bei dem die Platzhalter_1,_2etc. die eigentlichen Parameter darstellen. Beim "Aufruf" desfunction-Objekts werden die Argumente (im Beispiel 23 und 42) an die vonfunctiongespeicherte Funktion weitergeleitet.Ausführlichere Erklärungen findest du bei Boost.Bind.
-
Noch ergänzend zu
tr1::function:
Der eigentliche Vorteil von function gegenüber einem gewöhnlichen Pointer auf eine Funktion ist, dass die Funktion nicht genau diesen Parameter und genau diesen Rückgabewert haben muss, sondern dass die besagten Werte lediglich in die Ausgangswerte konvertierbar sein müssen. Außerdem akzeptiert er dank Templates auch Funktoren als Parameter.
Beispiel:// Erste Funktion int f(int c) { return c * c; } // Zweite Funktion double d(float f) { return f * f; } // Funktor struct c { int operator ()(int d) { return d + d; } }; // Ruft Fkt.-Ptr. auf void aufruf(int (*fptr)(int)) { fptr(34); } // Ruft Template auf template <typename T> void aufruf2(T t) { t(54); } // Ruft tr1::function auf void aufruf3(std::tr1::function<int (int)> fkt) { fkt(43); } aufruf(f); // Prima! aufruf(c()); // oh-oh! c kann nicht in int (*)(int) konvertiert werden aufruf(d); // oh-oh! double (*)(float) kann nicht in int (*)(int) konvertiert werden // Optionaler Tpl-Parameter zur Veranschaulichung aufruf2<int (int)>(f); // Prima! aufruf2<c>(c()); // Prima! aufruf2<double (float)>(d); // Prima! // Prima! Mit Konvertierungen aufruf3(f); aufruf3(c()); aufruf3(d);