Wie Callback implementieren?
-
manni66 schrieb:
Nanni schrieb:
manni66 schrieb:
Wenn du hinter dem &App im bind-Aufruf tatsächlich ein Leerzeichen stehen hast, solltest du das mal entfernen.
Habe ich nicht. Habs nur falsch abgetippt-
manni66 schrieb:
Warum heißt es einmal oox::InputData, einmal nur InputData?
Eigentlich ist der Code aufgesplittet auf .h und .cpp und im Header deklariere ich den Namespaces explizit und im .cpp habe ich eine using Direktive.
Wie bitteschön soll jemand etwas sinnvolles zu deinen Fehlermeldungen sagen, wenn du nicht den Code zeigst, der zu den Meldungen führt?
Die relevanten Stellen sind gepostet.
Übrigens ist die Fehlermeldung 5mal so lange als das was ich zitiert habe. Und dennoch so hilfreich wie ein Kropf.
-
Ich würd auch sagen, da fehlt was. Poste doch Mal alles... Bei den Dingern muss man soweit runterscrollen, bis die einen auf den eigenen Code verweisen, dann ist das auch nicht weiter kompliziert zu lesen, das darüber ist halt überflüssig.
-
Zu den Fehlermeldungen bei Templates, lass die beim Visual Studio nicht die Ausgabe sondern die Fehlerliste anzeigen, da sind alle Fehler schön verstämdlich für jedermann aufgelistet, auch bei Templates

-
Du bindest in deinem Beispiel nur "this", also einen Parameter. Die Funktion hat - aus Sicht von bind() - aber 3 Parameter: das implizite this, was du bindest, und noch zwei weitere.
Bei bind() musst du aber immer alle Parameter angeben.
Für Parameter die du nicht binden (festlegen) willst, sondern die Parameter bleiben sollen, gibt es dazu die Platzhalter _1, _2 etc. im Namespace std::placeholders.Die Nummer bezieht sich dabei auf die Nummer des Parameters der *neuen* Funktion.
Also
// foo->setInputCallback( std::bind(&App ::inputHandler, this) ); foo->setInputCallback( std::bind(&App::inputHandler, this, std::placeholders::_1, std::placeholders::_2) );Bzw. alternativ
using namespace std::placeholders; // foo->setInputCallback( std::bind(&App ::inputHandler, this) ); foo->setInputCallback( std::bind(&App::inputHandler, this, _1, _2) );So sollte es IMO funktionieren.
-
manni66 schrieb:
Wenn du hinter dem &App im bind-Aufruf tatsächlich ein Leerzeichen stehen hast, solltest du das mal entfernen.
Das Leerzeichen an der Stelle ist zwar unüblich, aber durchaus erlaubt.
-
hustbaer schrieb:
Du bindest in deinem Beispiel nur "this", also einen Parameter. Die Funktion hat - aus Sicht von bind() - aber 3 Parameter: das implizite this, was du bindest, und noch zwei weitere.
Bei bind() musst du aber immer alle Parameter angeben.
Für Parameter die du nicht binden (festlegen) willst, sondern die Parameter bleiben sollen, gibt es dazu die Platzhalter _1, _2 etc. im Namespace std::placeholders.Die Nummer bezieht sich dabei auf die Nummer des Parameters der *neuen* Funktion.
Also
// foo->setInputCallback( std::bind(&App ::inputHandler, this) ); foo->setInputCallback( std::bind(&App::inputHandler, this, std::placeholders::_1, std::placeholders::_2) );Bzw. alternativ
using namespace std::placeholders; // foo->setInputCallback( std::bind(&App ::inputHandler, this) ); foo->setInputCallback( std::bind(&App::inputHandler, this, _1, _2) );So sollte es IMO funktionieren.
Danke

Mit den Änderung klappts tatsächlich. Hab ja gesagt, dass der relevante Code gepostet ist.

Hab mich aber dennoch für den InputHandler als Klasse entschieden, weil ich die ganze Syntax mit bind potthässlich finde
dev->setInputCallback( std::bind(&App::inputHandler, this, std::placeholders::_1, std::placeholders::_2 ) );vs
dev->setInputCallback( mInputHandler );
-
std::bind()ist konsistent, übersichtlich und vor allem sehr flexibel, wenn man das Grundprinzip verstanden hat. Kommt mir wie ein schlechter Deal vor, nur wegen der Syntax wieder zumInputHandlerzurückzugreifen. Zumal du im Endeffekt wahrscheinlich einiges mehr an Code (grösstenteils Boilerplate) benötigst, um das Gleiche zu erreichen.Aber natürlich machst du den Namensraum
std::placeholderslokal bekannt, sonst musst du dich über umständliche Platzhalter nicht wundern...
-
bindist für den Aufrufer wesentlich flexibler. Er kann ganz einfach seine eigenen Klasse und Funktionen (jeweils mit eigenem Interface) ohne nennenswerten Aufwand als Callback registrieren, ohne jedesmal umständlich eine neue Klasse von InputHandler abzuleiten (das ist eher Java-Stil, weil es da nicht besser geht). Und wenn dem Benutzer diebind-Syntax nicht gefällt (das hat ja gar nichts mit dir zu tun, du willst ja nur eine entsprechendestd::function), kann er immernoch einen eigenen Funktor schreiben (Klasse mit überladenem ()-Operator).
-
ipsec schrieb:
Und wenn dem Benutzer die
bind-Syntax nicht gefällt (das hat ja gar nichts mit dir zu tun, du willst ja nur eine entsprechendestd::function), kann er immernoch einen eigenen Funktor schreiben (Klasse mit überladenem ()-Operator).Oder, da sich Nanni ja scheinbar schon mit std::function im C++0x-Bereich bewegt, auch einfach ein lambda:
foo->setInputCallback([&](const InputData& inputData, float deltaTime) { inputHandler(inputData, deltaTime); } );
-
Nanni schrieb:
Und wieso sind in C++ die Fehlermeldungen oft so ein riesen Haufen kryptischer Scheiß?

C++ ist die wohl am schwierigst zu parsende Sprache der Welt. Ein Wunder, dass ein Compiler den Code überhaupt übersetzen kann. Das geht, da eindeutig definiert ist (im C++ Standard) was richtig ist und was nicht. Der Compiler gibt dir die Informationen, die er hat. Woher soll er wissen, dass hier Typ XY hineingehört? Und sei froh, dass er dir so viel Information gibt, wie möglich. Er könnte genauso sagen "error in file XY".