Für eine Klasse möchte ich einige Funktionszeiger auf Mitgliedsfunktionen derselben Klasse in einem Objekt map
speichern std::function
. Aber ich versage gleich zu Beginn mit diesem Code:
class Foo {
public:
void doSomething() {}
void bindFunction() {
// ERROR
std::function<void(void)> f = &Foo::doSomething;
}
};
Ich erhalte error C2064: term does not evaluate to a function taking 0 arguments
in xxcallobj
Kombination mit einigen seltsamen Vorlageninstanziierungsfehlern. Derzeit arbeite ich unter Windows 8 mit Visual Studio 2010/2011 und unter Win 7 mit VS10 schlägt dies ebenfalls fehl. Der Fehler muss auf einigen seltsamen C ++ - Regeln basieren, denen ich nicht folge
std::function
this
std::function<void(Foo*, int, int)> = &Foo::doSomethingArgs
Entweder du brauchst
Damit Sie es auf einer beliebigen Instanz aufrufen können oder beispielsweise eine bestimmte Instanz binden müssen
this
quelle
this
?Wenn Sie eine Member-Funktion ohne die Klasseninstanz speichern müssen , können Sie Folgendes tun:
Wie würde der Speichertyp ohne Auto aussehen ? Etwas wie das:
Sie können diesen Funktionsspeicher auch an eine Standardfunktionsbindung übergeben
Frühere und zukünftige Hinweise: Eine ältere Schnittstelle std :: mem_func war vorhanden, wurde jedoch inzwischen nicht mehr unterstützt. Nach C ++ 17 gibt es einen Vorschlag, den Zeiger auf Mitgliedsfunktionen aufrufbar zu machen . Dies wäre sehr willkommen.
quelle
std::mem_fn
wurde nicht entfernt; eine Menge unnötiger Überlastungen waren. Andererseitsstd::mem_fun
wurde mit C ++ 11 veraltet und wird mit C ++ 17 entfernt.template<class R, class T> unspecified mem_fn(R T::*);
und sie wird nicht verschwinden.Leider können Sie in C ++ kein aufrufbares Objekt direkt abrufen, das auf ein Objekt und eine seiner Mitgliedsfunktionen verweist.
&Foo::doSomething
gibt Ihnen einen "Zeiger auf die Elementfunktion", der sich auf die Elementfunktion bezieht, jedoch nicht auf das zugehörige Objekt.Es gibt zwei Möglichkeiten, dies
std::bind
zu umgehen. Eine besteht darin , den "Zeiger auf diethis
Elementfunktion " an den Zeiger zu binden . Die andere Möglichkeit besteht darin, ein Lambda zu verwenden, das denthis
Zeiger erfasst und die Elementfunktion aufruft.Letzteres würde ich vorziehen.
Wenn g ++ mindestens eine Mitgliedsfunktion daran bindet, führt dies zu einem Objekt mit einer Größe von drei Zeigern. Wenn Sie dies einem Objekt zuweisen, wird ein
std::function
dynamischer Speicher zugewiesen.Auf der anderen Seite ist ein Lambda, das erfasst,
this
nur ein Zeiger groß. Wenn Sie es einem Lambda zuweisen,std::function
führt dies nicht zu einer dynamischen Speicherzuweisung mit g ++.Obwohl ich dies mit anderen Compilern nicht überprüft habe, vermute ich, dass dort ähnliche Ergebnisse gefunden werden.
quelle
Sie können Funktoren verwenden, wenn Sie eine weniger allgemeine und präzisere Steuerung unter der Haube wünschen. Beispiel mit meiner win32-API zum Weiterleiten einer API-Nachricht von einer Klasse an eine andere Klasse.
IListener.h
Listener.h
Dispatcher.h
Verwendungsprinzipien
Viel Glück und vielen Dank für den Wissensaustausch.
quelle
Sie können dies vermeiden
std::bind
:quelle