Lambda-Ausdrücke werden implementiert, indem eine Klasse mit einem überladenen Funktionsaufrufoperator erstellt und Variablen als Mitglieder referenziert werden. Dies deutet darauf hin, dass die Größe von Lambda-Ausdrücken abhängig von der Anzahl der referenzierten Variablen variiert. Allerdings muss std::function eine feste Größe haben. Das Verständnis der Implementierung von std::function ist von entscheidender Bedeutung.
Typlöschung für Funktoren variabler Größe
std::function verwendet eine Technik namens Typlöschung, um Funktoren von zu verarbeiten variable Größen. Betrachten Sie ein vereinfachtes Beispiel von std::function, das einen Funktionszeiger auf int(double) umschließt:
struct callable_base { virtual int operator()(double d) = 0; virtual ~callable_base() {} }; template <typename F> struct callable : callable_base { F functor; callable(F functor) : functor(functor) {} virtual int operator()(double d) { return functor(d); } }; class function_int_double { std::unique_ptr<callable_base> c; public: template <typename F> function(F f) { c.reset(new callable<F>(f)); } int operator()(double d) { return c(d); } };
In diesem Beispiel speichert std::function einen unique_ptr im polymorphen Typ callable_base. Für verschiedene Funktoren werden neue, von callable_base abgeleitete Typen erstellt und dynamisch instanziiert. Das std::function-Objekt behält eine konsistente Größe bei und nimmt Funktoren unterschiedlicher Größe im Heap auf.
Dynamischer Versand und Optimierung
Um die Leistung zu verbessern, werden reale Implementierungen durchgeführt von std::function optimieren den dynamischen Versand und nutzen Optimierungen für kleine Objekte. Das zugrunde liegende Konzept bleibt jedoch dasselbe.
Verhalten von std::function-Kopien
Kopien von std::function werden von Kopien des aufrufbaren Objekts begleitet, das sie kapseln . Dies wird durch den folgenden Test bestätigt:
int main() { int value = 5; typedef std::function<void()> fun; fun f1 = [=]() mutable { std::cout << value++ << '\n' }; fun f2 = f1; f1(); fun f3 = f1; f2(); f3(); }
Die Ausgabe zeigt (5, 5, 6), was angibt, dass Kopien des Funktionsobjekts erstellt werden, anstatt den Status zu teilen.
Dieses Verständnis der Implementierung von std::function gewährleistet die effiziente Verwendung mit Funktoren unterschiedlicher Größe.
Das obige ist der detaillierte Inhalt vonWie geht „std::function' mit Funktoren variabler Größe um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!