std::bind
ist für Teilfunktionsanwendungen .
Angenommen, Sie haben ein Funktionsobjekt, f
das drei Argumente akzeptiert:
f(a,b,c);
Sie möchten ein neues Funktionsobjekt, das nur zwei Argumente akzeptiert, definiert als:
g(a,b) := f(a, 4, b);
g
ist eine "Teilanwendung" der Funktion f
: Das mittlere Argument wurde bereits angegeben, und es sind noch zwei übrig.
Sie können verwenden std::bind
, um zu erhalten g
:
auto g = bind(f, _1, 4, _2);
Dies ist prägnanter als das Schreiben einer Funktorklasse, um dies zu tun.
Der Artikel, auf den Sie verlinken, enthält weitere Beispiele. Sie verwenden es im Allgemeinen, wenn Sie einen Funktor an einen Algorithmus übergeben müssen. Sie haben eine Funktion oder einen Funktor, der / die fast die gewünschte Arbeit erledigt, aber konfigurierbarer ist (dh mehr Parameter hat) als der Algorithmus verwendet. Sie binden also Argumente an einige der Parameter und überlassen den Rest dem Algorithmus zum Ausfüllen:
// raise every value in vec to the power of 7
std::transform(vec.begin(), vec.end(), some_output, std::bind(std::pow, _1, 7));
Hier werden pow
zwei Parameter verwendet und können auf jede Potenz erhöht werden , aber alles, was uns wichtig ist, ist die Erhöhung auf die Potenz von 7.
Als gelegentliche Verwendung, die keine Teilfunktionsanwendung ist, bind
können die Argumente auch in eine Funktion umgeordnet werden:
auto memcpy_with_the_parameters_in_the_right_flipping_order = bind(memcpy, _2, _1, _3);
Ich empfehle nicht, es zu verwenden, nur weil Ihnen die API nicht gefällt, aber es hat potenzielle praktische Verwendungsmöglichkeiten, zum Beispiel, weil:
not2(bind(less<T>, _2, _1));
ist eine Funktion, die kleiner oder gleich ist (unter der Annahme einer Gesamtordnung, bla bla). Dieses Beispiel ist normalerweise nicht erforderlich, da es bereits einen gibt std::less_equal
(es verwendet <=
eher den Operator als <
. Wenn diese also nicht konsistent sind, benötigen Sie dies möglicherweise und müssen den Autor der Klasse möglicherweise auch mit einem Cluestick besuchen). Es ist jedoch die Art von Transformation, die sich ergibt, wenn Sie einen funktionalen Programmierstil verwenden.
myThread=boost::thread(boost::bind(&MyClass::threadMain, this))
std::function
?pow
Beispiel wird nicht kompiliert. Dapow
es sich um eine überladene Funktion handelt, müssen Sie manuell angeben, welche Überlastung vorliegt. Die Bindung kann nicht vom Anrufer des resultierenden Funktors abgeleitet werden. ZBstd::transform(vec.begin(), vec.end(), out.begin(), std::bind((double (*)(double, int))std::pow, _1, 7));
std::bind
mit derthis
Verwendung als 2. Argument zusammen. Können Sie diesen Anwendungsfall bitte näher erläutern?std::placeholders::_1
. Ich habe eine Weile gebraucht, um herauszufinden, warum dies nicht kompiliert wurde.Eine der Hauptanwendungen von std :: function und std :: bind sind generischere Funktionszeiger. Sie können es verwenden, um einen Rückrufmechanismus zu implementieren. Eines der beliebtesten Szenarien ist, dass Sie eine Funktion haben, deren Ausführung lange dauern wird, aber nicht auf die Rückkehr warten möchten. Dann können Sie diese Funktion in einem separaten Thread ausführen und ihr einen Funktionszeiger geben, den sie ausführen wird Rückruf nach Abschluss.
Hier ist ein Beispielcode für die Verwendung:
quelle
std :: bind wurde nach dem Vorschlag, Boost Bind aufzunehmen, in die Bibliothek gewählt. In erster Linie handelt es sich um eine Teilfunktionsspezialisierung, bei der Sie einige Parameter korrigieren und andere im laufenden Betrieb ändern können. Dies ist eine Bibliotheksmethode für Lambdas in C ++. Wie von Steve Jessop beantwortet
Jetzt, da C ++ 11 Lambda-Funktionen unterstützt, habe ich keine Versuchung mehr, std :: bind zu verwenden. Ich würde lieber Curry (teilweise Spezialisierung) mit Sprachfunktion als Bibliotheksfunktion verwenden.
std :: function-Objekte sind polymorphe Funktionen. Die Grundidee besteht darin, alle aufrufbaren Objekte austauschbar referenzieren zu können.
Ich möchte Sie für weitere Details auf diese beiden Links verweisen:
Lambda funktioniert in C ++ 11: http://www.nullptr.me/2011/10/12/c11-lambda-having-fun-with-brackets/#.UJmXu8XA9Z8
Aufrufbare Entität in C ++: http://www.nullptr.me/2011/05/31/callable-entity/#.UJmXuMXA9Z8
quelle
std::bind
gab es nie ohne Lambdas - beide Funktionen wurden in C ++ 11 eingeführt. Wir hattenbind1st
undbind2nd
die abgemagerte Versionen von C ++ 11 binden.Ich habe es vor langer Zeit verwendet, um einen Plugin-Thread-Pool in C ++ zu erstellen. Da die Funktion drei Parameter verwendet hat, können Sie so schreiben
Angenommen, Ihre Methode hat die Signatur:
So erstellen Sie ein Funktionsobjekt zum Binden der drei Parameter
Um die Parameter zu binden, müssen wir nun eine Binder-Funktion schreiben. Also, hier geht es:
Und eine Hilfsfunktion zur Verwendung der Klasse binder3 - bind3:
und hier uns wie man es nennt
Anmerkung: f3 (); ruft die Methode task1-> ThreeParameterTask (21,22,23) auf;
Weitere wichtige Details -> http://www.codeproject.com/Articles/26078/AC-Plug-in-ThreadPool-Design
quelle