Warum std :: bind über Lambdas in C ++ 14?
Vor C++11, die ich verwendet boost::bind
oder boost::lambda
viel. Die bind
Teil und schaffte es in der standard-Bibliothek (std::bind
) der andere Teil wurde Teil der core-Sprache (C++ Lambda-Ausdrücke) und die Nutzung von lambdas viel einfacher. Heute habe ich kaum Verwendung std::bind
da kann ich fast alles mit C++ Lambda-Ausdrücke. Es gibt eine gültige use-case für std::bind
die ich mir denken kann:
struct foo
{
typedef void result_type;
template < typename A, typename B >
void operator()(A a, B b)
{
cout << a << ' ' << b;
}
};
auto f = bind(foo(), _1, _2);
f( "test", 1.2f ); //will print "test 1.2"
Den C++14-äquivalent für das wäre
auto f = []( auto a, auto b ){ cout << a << ' ' << b; }
f( "test", 1.2f ); //will print "test 1.2"
Viel kürzer und übersichtlicher. (In C++11 das doch nicht funktionieren, weil der auto-Parameter.) Gibt es eine andere zulässige Verwendung für std::bind
schlagen der C++ - lambdas alternative oder ist std::bind
überflüssig mit C++14?
InformationsquelleAutor der Frage Ralph Tandetzky | 2013-06-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Scott Meyers gab eine sprechen über diese. Dies ist, was ich mich erinnere:
In C++14 gibt es nichts brauchbares binden können, dass Sie nicht auch mit lambdas.
In C++11 aber es gibt einige Dinge, die nicht getan werden kann mit lambdas:
Können Sie nicht verschieben Sie die Variablen, die während der Aufnahme beim erstellen der Lambda-Ausdrücke. Variablen werden immer gefangen als lvalues. Zum binden können Sie schreiben:
Ausdrücke können nicht erobert werden, nur die Bezeichner können. Zum binden können Sie schreiben:
Überlastung Argumente für die Funktion von Objekten. Dies war bereits in der Frage.
In C++14 alle diese möglich.
Verschieben Beispiel:
Expression-Beispiel:
Siehe Frage
Perfect forwarding: Sie können schreiben,
Einige Nachteile von binden:
Binden bindet mit Namen und als ein Ergebnis, wenn Sie mehrere Funktionen mit dem gleichen Namen (überladene Funktionen) zu binden, die nicht wissen, welche zu benutzen. Das folgende Beispiel wird nicht kompilieren, während lambdas hätte kein problem mit ihm:
Auf der anderen Seite lambdas könnten theoretisch mehr erzeugen template-code als binden. Da für jedes lambda-Sie erhalten einen eindeutigen Typ. Für binden, es ist nur, wenn Sie verschiedene Argumenttypen und eine andere Funktion (ich vermute, dass in der Praxis ist es jedoch nicht sehr oft passieren, binden Sie einige Zeit mit den gleichen Argumenten und Funktion).
Was Jonathan Wakely erwähnt in seiner Antwort, ist eigentlich ein Grund mehr, Sie nicht zu verwenden, binden. Ich kann nicht sehen, warum würden Sie wollen, um schweigend ignorieren Argumente.
InformationsquelleAutor der Antwort BertR
std::bind
noch eine Sache, die polymorphe Lambda-Ausdrücke können nicht: aufrufen von überladenen FunktionenDen Anruf wrapper erstellt, indem die bind-Ausdruck nennt verschiedene Funktionen, je nach den Argumenten, die Sie geben es, die Schließung von C++14 polymorphe lambda kann auf unterschiedliche Arten Argumente aber können nicht nehmen Sie eine andere Anzahl der Argumente und ruft immer (Spezialisierungen) die gleiche Funktion auf dem Verschluss. Korrektur: siehe die Kommentare unten
Wrapper zurückgegeben
std::bind
können auch aufgerufen werden, mit zu viele Argumente, und es wird ignoriert werden, in der Erwägung, dass eine closure erzeugt, die durch einen lambda-Ausdruck zu diagnostizieren versucht, pass zu viele Argumente ... aber ich denke nicht, dass das ein Vorteilstd::bind
🙂InformationsquelleAutor der Antwort Jonathan Wakely
Für mich, eine gültige Verwendung für
std::bind
zu machen, ist es klar, dass ich mit einem member-Funktion als Prädikat. Das ist, wenn alles, was ich tun muss ist Aufruf einer member-Funktion, die es binden. Wenn ich extra Sachen mit dem argument (außer dem Aufruf eines memeber-Funktion), ist es eine lambda:InformationsquelleAutor der Antwort utnapistim
Weiterer Unterschied ist, dass Argumente zu binden, müssen kopiert oder verschoben werden, während ein lambda-Ausdruck können Variablen verwenden, gefangen-by-reference. Siehe Beispiel unten:
Nicht sicher, ob es möglich ist, um dieses Problem zu lösen, verwenden Sie binden den oben-ohne änderung der Signatur von
void p(const int&)
.InformationsquelleAutor der Antwort Zitrax
Manchmal ist es einfach weniger code. Bedenken Sie:
Dann
vs lambda
Ich denke, das binden ist einfacher zu Lesen hier im Vergleich zu den lambda-Ausdruck, der aussieht wie eine https://en.wikipedia.org/wiki/Brainfuck
InformationsquelleAutor der Antwort AlexTheo