2010-06-21 14 views
13

Ich schaue mir die Boost-Bibliotheken an, die in C++ 's Technical Report 1 enthalten waren und versuche zu verstehen, was jeder tut.Wozu boost :: mem_fn, wenn wir boost :: bind haben?

Ich habe gerade ein Beispiel für boost::mem_fn ausgeführt und jetzt frage ich mich, was ist der Sinn der Verwendung es anstelle der besseren boost::bind. Soweit ich verstehe, geben beide ein Funktionsobjekt zurück, das auf eine Elementfunktion verweist. Ich finde mem_fn so begrenzt, dass ich kein Szenario finden kann, in dem es besser wäre als bind.

Fehle ich etwas? Gibt es Fälle, in denen bind nicht mem_fn ersetzen kann?

Antwort

7

mem_fn ist viel kleiner als bind, wenn Sie also nur die Funktionalität von mem_fn benötigen ist es viel weniger Code in ziehen.

2

Nun, Bindung hängt von mem_fun ab, also los gehts. Wie und warum werde ich für dich aufbrechen, um zu entdecken, da, obwohl interessant, ich habe nicht die Zeit zu untersuchen, sofort (Bind ist kompliziert).

1

boost::lambda hat eine ähnliche Überschneidung der Funktionalität mit den beiden Sie erwähnt. Ich denke, sie alle entwickelten sich mit ähnlicher Absicht, etwa zur gleichen Zeit, mit unterschiedlichen Ansätzen, was zu Verwirrung und Inkompatibilitätsproblemen führte. Es wäre schön, wenn sie alle unter einem lambda Regenschirm zusammengeführt würden.

Also, nein, es gibt kein übergreifendes Design, das die Koexistenz beider Bibliotheken fordert.

+3

Das Merkwürdige ist, dass sowohl 'bind' als auch' mem_fn' es in den C++ Technical Report 1 geschafft haben, und das C++ - Komitee soll ziemlich streng sein. Haben sie nicht bemerkt, dass wir Funktionen duplizieren? –

5

mem_fn ist kleiner und schneller als bind. Versuchen Sie das folgende Programm mit Ihren Lieblings-Compiler und vergleichen:

  1. Die Größe der resultierenden ausführbaren und
  2. Die Anzahl der Sekunden gemeldet als ausgegeben werden.

Sie können die Leistung von bind gegen mem_fn vergleichen, indem 1 zu einer 0 in der #if Linie zu ändern.

#include <iostream> 
#include <functional> 
#include <chrono> 

struct Foo 
{ 
    void bar() {} 
}; 

int main(int argc, const char * argv[]) 
{ 
#if 1 
    auto bound = std::bind(&Foo::bar, std::placeholders::_1); 
#else 
    auto bound = std::mem_fn(&Foo::bar); 
#endif 
    Foo foo; 
    auto start = std::chrono::high_resolution_clock::now(); 
    for(size_t i = 0; i < 100000000; ++i) 
    { 
     bound(foo); 
    } 
    auto end = std::chrono::high_resolution_clock::now(); 
    auto delta = std::chrono::duration_cast< std::chrono::duration<double>>(end - start); 
    std::cout << "seconds = " << delta.count() << std::endl; 
    return 0; 
} 

Die Ergebnisse sind unterschiedlich, aber auf meinem aktuellen System der mem_fn Version der ausführbaren Datei ist 220 Bytes kleiner und läuft etwa doppelt so schnell wie die bind Version.

Und als Bonus-Feature, mem_fn nicht Sie benötigen zu erinnern std::placeholders::_1 wie bind does hinzufügen (auf Schmerz eines obskuren Fehler Templat-Compiler).

Also, bevorzugen Sie mem_fn, wenn Sie können.

+0

+1 für den Benchmark-Code. – felipou

+0

Ich denke, GCC-Optimierungen werden die Geschwindigkeitseffizienz für beide gleich machen. Ich habe gerade getestet "-O2" mit Ihrem Code (und etwas in der "bar" -Funktion zu drucken, sonst wird der Optimierer sehen, es macht nichts). Manchmal ist die "bind" -Version noch schneller. – felipou

+0

Sie sollten etwas hinzufügen wie 'statische volatile int i; i; 'in den' bar'-Textkörper, ansonsten kann der Compiler den leeren Funktionsaufruf optimieren (was in meinem Fall mit 'bind' und' mem_fn' wirklich passiert). Die Benchmark-Ergebnisse für 'bind' und' mem_fn' sind auf meinem PC gleich (* gcc 4.9 *, '-O3'),' mem_fn' ist nicht schneller als 'bind'. –

Verwandte Themen