std::function und Funktor mit Gedächtnis
-
Hallo,
wenn ich das folgende ausführe:
#include <iostream> #include <functional> struct functor { int value = 0; int operator()(int i) { return value += i; } }; class test { std::function<int(int)> f_; public: test(std::function<int(int)> f) : f_(f) {} void foo() { f_(3); } }; int main() { functor func; test t(func); t.foo(); std::cout << func.value << '\n'; // Outputs 0 }erhalte ich als Ausgabe "0". Ich würde aber gerne "3" als Ausgabe erhalten (also das "Gedächtnis" des Funktors erhalten). Geht das mit std::function als Argument überhaupt oder hab ich da einen Denkfehler drin?
-
Dein Denkfehler ist, dass dein struct 'functor' kopiert wird.
-
tkausl schrieb:
Dein Denkfehler ist, dass dein struct 'functor' kopiert wird.
Ok, und wie sage ich ihm dann dass eine Referenz von dem functor func verwendet werden soll und keine Kopie?
-
test t(std::ref(func));
-
Arcoth schrieb:
test t(std::ref(func));Lol.
Vielen Dank, das klappt

-
Um die Lösung zu verstehen musst du dir einmal die Deklaration des Konstruktors von std::function anschauen:
template< class F > function( F f );Dort werden über einen Template Parameter beliebige Funktionen/Funktionsobjekte akzeptiert. Bei einem so geschriebenen Konstruktor wird für F aber niemals ein Typ mit Referenz abgeleitet. Daher gabs es bei deiner ursprünglichen Lösung eine Kopie deines Objekts. Man muss also irgendwie dafür sorgen, dass der Konstruktor dein Objekt als Referenz übernimmt und speichert. Da es meistens böse ist Typen für Template Funktionen explizit anzugeben, und für Konstruktoren gar nicht möglich ist, brauchen wir also eine andere Möglichkeit dafür zu sorgen, dass F wenigstens sowas ähnliches wie eine Referenz wird. Dafür gibt es die Klasse std::reference_wrapper. Durch die Funktion std::ref kann man sich komfortabel ein Objekt dieser Klasse erzeugen. Der Typ F der also letztendlich an den Konstruktor von std::function übergeben wird lautet: std::reference_wrapper<functor>
-
Ok, das macht Sinn, danke

Wollte schon alles auf static umstellen, aber damit geht es jetzt

-
happystudent schrieb:
Wollte schon alles auf static umstellen
OMG

-
hustbaer schrieb:
OMG

Hehehe

Ja, nur temporär bis ich ne Lösung gefunden habe (dachte nicht dass es so einfach geht).