std::function
ist ein Typ -Löschen -Objekt. Das bedeutet, dass es die Details der Einführung einiger Vorgänge auslöscht und ihnen eine einheitliche Laufzeitschnittstelle bietet. Zum std::function
, die primäre1 Operationen sind Kopie/Bewegung, Zerstörung und "Aufruf" mit operator()
- Die 'Funktion wie Anrufbetreiber'.
In weniger abstruse Englisch bedeutet das, dass das std::function
Kann fast jedes Objekt enthalten, das wie ein Funktionszeiger in der Art und Weise wirkt, wie Sie es nennen.
Die Signatur, die es unterstützt, geht in die Winkelklammern: std::function<void()>
Nimmt keine Argumente und gibt nichts zurück. std::function< double( int, int ) >
nimmt zwei int
Argumente und Rückgaben double
. Im Algemeinen, std::function
Unterstützt das Speichern eines funktionsähnlichen Objekts, dessen Argumente von seiner Argumentliste konvertiert werden können und deren Rückgabewert auf seinen Rückgabewert konvertiert werden kann.
Es ist wichtig zu wissen std::function
und Lambdas sind unterschiedlich, wenn auch kompatibel, Bestien.
Der nächste Teil der Linie ist ein Lambda. Dies ist eine neue Syntax in C ++ 11, um die Möglichkeit hinzuzufügen, einfache funktionsähnliche Objekte zu schreiben-Objekte, die aufgerufen werden können ()
. Solche Objekte können in a gelöscht und gespeichert werden std::function
Auf Kosten einiger Laufzeit über Kopf.
[](){ code }
Insbesondere ist ein wirklich einfaches Lambda. Es entspricht dem:
struct some_anonymous_type {
some_anonymous_type() {}
void operator()const{
code
}
};
Eine Instanz des obigen einfachen Pseudo-Funktionstyps. Eine tatsächliche Klasse wie die oben genannte wird vom Compiler mit einem implementierenden eindeutigen Namen "erfunden" (oft einschließlich Symbole, die kein benutzerdefinierter Typ enthalten kann) (ich weiß nicht, ob es möglich ist, dass Sie dem Standard ohne Erfindung folgen können Eine solche Klasse, aber jeder Compiler, von dem ich kenne, erstellt tatsächlich die Klasse).
Die volle Lambda -Syntax sieht aus wie:
[ capture_list ]( argument_list )
-> return_type optional_mutable
{
code
}
Aber viele Teile können weggelassen oder leer gelassen werden. Die Capture_List entspricht sowohl dem Konstruktor des resultierenden anonymen Typs als auch seinen Mitgliedsvariablen, das Argument_List die Argumente der operator()
, und der Rückgabetyp den Rückgabetyp. Der Konstruktor der Lambda -Instanz wird auch auf magische Weise auf magische Weise aufgerufen, wenn die Instanz mit der Capture_List erstellt wird.
[ capture_list ]( argument_list ) -> return_type { code }
im Grunde wird
struct some_anonymous_type {
// capture_list turned into member variables
some_anonymous_type( /* capture_list turned into arguments */ ):
/* member variables initialized */
{}
return_type operator()( argument_list ) const {
code
}
};
Beachten Sie das in C ++ 20 Vorlagenargumente wurden zu Lambdas hinzugefügt, und das ist nicht oben nicht behandelt.
[]<typename T>( std::vector<T> const& v ) { return v.size(); }
1 Darüber hinaus wird RTTI gespeichert (Typid) und der Operation vom Typ Cast-Back-to-Original ist enthalten.