2016-04-01 9 views
5

Ich verstehe nicht ganz, was eine Instanz von std::function tatsächlich enthält.Sollte ich std :: function by-value oder (rvalue) -reference übergeben?

Ist es effizienter, es als Wert oder als Referenz zu übergeben?

Was sind die Leistungseffekte in den folgenden Beispielen?

by-Wert:

void printStats(std::function<void(const char *)> printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 

von rvalue-Referenz:

void printStats(std::function<void(const char *)>&& printer); 
. . . 
std::string tmp; 
printStats([&tmp](const char * msg){ tmp += msg; }); 
+0

Meinst du Bass durch Referenz oder R-Wert Referenz? Dein Titel sagt eine Sache, aber der Code eine andere. Rvalue-Referenz und Lvalue-Referenz funktionieren anders. – NathanOliver

+0

Ich denke, die einfache Antwort ist By-Wert, aber nur für den Fall, dass Sie nicht wussten: [wann Vorlagen über 'std :: function 'zu verwenden sind] (http://stackoverflow.com/questions/14677997/stdfunction-vs-template) – Maikel

+0

Das Kopieren einer 'std :: function' erfordert in der Regel eine dynamische Speicherzuordnung, ist daher etwas teuer und sollte daher als Referenz übergeben werden. – nwp

Antwort

5

Zuerst std::function erforderlich Zuweisung in dem Fall zu vermeiden, wo das Ziel ein Funktionszeiger von std::reference_wrapper ist; Implementierungen sind encouraged to avoid allocation for "small" targets:

[...] Wenn beispielsweise f ‚s Ziel ein Objekt nur einen Zeiger oder eine Referenz auf ein Objekt und ein Mitglied Funktionszeiger hält.

Das bedeutet, dass ein std::function dessen Ziel Kopieren groß wird eine Zuordnung und eine Kopie des Ziels (Referenzzählung nicht erlaubt ist, da das Ziel veränderbaren Zustand haben kann) beinhalten. In Ihrem speziellen Fall wird die Kopie jedoch entfernt, da Sie Ihre Funktion mit einem temporären prvalue aufrufen.

In Ihrem speziellen Fall, da Sie die Funktion sofort aufrufen, müssen Sie sich keine Sorgen machen, dass Sie den Besitz übernehmen, also wäre es besser, die Funktion durch const reference zu verwenden. Die Verwendung der Rvalue-Referenz würde einem Benutzer Kopfschmerzen bereiten, der über einen vorhandenen Lvalue- oder Const-Verweis auf eine Funktion verfügt. Sie müssten std::move es (im ersten Fall) oder erstellen Sie eine prvalue temporäre Kopie (im letzteren Fall).

+1

"Ermutigt "ist nicht das Gleiche wie" erforderlich ". Darüber hinaus ist dieser zitierte Text in einer ** Notiz ** und Noten sind nicht normativ. –

Verwandte Themen