Ich habe bisher Funktionszeiger verwendet, wie dieses Format in C ++. Ich habe ab und zu einige Anwendungen und ich frage mich, ob es etwas anderes in c ++ 11/14 als Alternative gibt.
%Vor%Ich habe mir diese Frage angesehen, konnte sie aber nicht verstehen irgendwelche Vorteile gegenüber der traditionellen Verwendung von Funktionszeigern. Auch ich würde gerne fragen, ob es irgendwas falsches (nicht empfohlenes) Ding mit Funktionszeigern gibt, da ich nie jemanden sehe, der sie benutzt. Oder irgendeine andere alternative Gegenwart.
Ich möchte auch fragen, ob etwas falsch ist (nicht empfohlen) Sache mit Funktionszeigern, da ich nie jemanden benutze sie.
Ja . Funktionszeiger sind schreckliche, schreckliche Dinge. Erstens unterstützen sie nicht, generisch zu sein - also können Sie keinen Funktionszeiger nehmen, der, zum Beispiel, std::vector<T>
für irgendeine T
benötigt. Zweitens, sie unterstützen nicht, gebunden zu sein, so dass, wenn irgendjemand in der Zukunft irgendjemand jemals auf einen anderen Staat verweisen möchte, sind sie völlig verschraubt. Dies ist besonders schlimm, da dies this
für Memberfunktionen enthält.
Es gibt zwei Möglichkeiten, Funktionen in C ++ 11 zu verwenden. Die erste besteht darin, eine Vorlage zu verwenden. Die zweite ist die Verwendung von std :: function.
Die Vorlage sieht irgendwie so aus:
%Vor%Die Hauptvorteile hier sind, dass es jede Art von Funktionsobjekt akzeptiert, einschließlich Funktionszeiger, Lambda, Funktor, Bindungsergebnis, was auch immer, und F kann eine beliebige Anzahl von Funktionsaufforderungen mit jeder Signatur, einschließlich Vorlagen, haben kann irgendeine Größe mit irgendeinem gebundenen Zustand haben. Es ist also super-flexibel. Es ist auch maximal effizient, da der Compiler den Operator inline und den Status direkt im Objekt übergeben kann.
%Vor%Der Hauptnachteil hier ist die üblichen Nachteile von Vorlagen - es funktioniert nicht für virtuelle Funktionen und muss in der Kopfzeile definiert werden.
Der andere Ansatz ist std::function
. std::function
hat viele der gleichen Vorteile - es kann eine beliebige Größe haben, an jeden Status gebunden werden und alles, was aufrufbar ist, aber ein Paar aushandeln. Hauptsächlich wird die Signatur zur Zeit der Typdefinition festgelegt, so dass Sie kein std::function<void(std::vector<T>)>
für einige noch zu erkennende T
haben können, und es kann auch eine dynamische Indirektion / Zuweisung geben (falls möglich). t SBO). Der Vorteil dabei ist, dass std::function
ein reeller konkreter Typ ist, den Sie wie bei jedem anderen Objekt weitergeben können, so dass er als virtueller Funktionsparameter und solche Dinge verwendet werden kann.
Grundsätzlich sind Funktionszeiger unglaublich begrenzt und können nichts Interessantes tun und machen die API unglaublich unflexibel. Ihre abscheuliche Syntax ist eine Pisse im Ozean und das Reduzieren mit einem Template-Alias ist urkomisch, aber sinnlos.
Die Frage, die Sie erwähnen, schlägt std :: function vor, betont aber nicht (oder erwähnt überhaupt) ihren Wert, wenn sie mit std :: bind kombiniert wird.
Ihr Beispiel ist das einfachste, aber nehmen Sie an, Sie haben ein
%Vor%Ein Funktionszeiger kann mehr oder weniger die gleichen Dinge tun. Angenommen, Sie benötigen eine Funktion g (int), die f ist, wobei der zweite Parameter an 0 gebunden ist. Mit Funktionszeigern können Sie nicht viel anfangen, mit der std :: -Funktion können Sie dies tun:
%Vor%Ich habe mir diese Frage angeschaut, konnte aber keine verstehen Vorteile gegenüber der traditionellen Verwendung von Funktionszeigern. Auch ich würde gerne fragen, gibt es irgendwas falsches (nicht zu empfehlen) ding mit Funktionszeiger verwenden, da ich nie jemanden sehe, der sie benutzt.
Normale "globale" Funktionen haben normalerweise keinen Status. Während es während des Traversals im funktionalen Programmierparadigma nicht unbedingt gut ist, einen Zustand zu haben, kann manchmal ein Zustand nützlich sein, wenn er sich orthogonal auf das bezieht, was geändert wurde (Heuristik als Beispiel). Hier haben Funktoren (oder Funktionsobjekte) den Vorteil.
Normale Funktionen sind nicht sehr gut (Erstellen von Funktionen auf höherer Ebene von Funktionen auf niedrigerer Ebene.
Normale Funktionen erlauben es nicht, zusätzliche Parameter im laufenden Betrieb zu binden.
Manchmal können normale Funktionen als Ersatz für Lambdas dienen, und umgekehrt, je nach Kontext. Oft möchte man keine spezielle Funktion schreiben, nur weil Sie während des "Container Traversal" eine sehr lokale / spezifische Anforderung haben.
Als eine Alternative zu traditionellen Funktionszeigern hat C ++ 11 Vorlagen-Alias eingeführt in Kombination mit variadischen Vorlagen könnte der Funktionszeiger sintax vereinfacht werden. Im Folgenden ein Beispiel für die Erstellung eines Funktionszeigers "Vorlage":
%Vor%Es kann so verwendet werden:
%Vor%Auch kann es gut mit Funktionsüberlastungen umgehen:
%Vor%Und kann als eine hübsche Methode verwendet werden, Funktionszeigerparameter zu deklarieren:
%Vor% Dieser Template-Alias könnte als Alternative zu std::function
verwendet werden, der weder Nachteile noch Vorteile hat ( gute Erklärung hier) ).
Kurz gesagt, ich denke, dass Vorlagen-Alias in Kombination mit variadischen Vorlagen eine gute, nette, saubere und moderne C ++ - Alternative zu rohen Funktionszeigern ist (dieser Alias ist immer noch Funktionszeiger), aber std::function
ist gut, nett, ordentlich und modern C ++ auch mit guten Vorteilen zu berücksichtigen. Das Einbinden von Funktionszeigern (oder Alias) oder die Auswahl von std::function
liegt an Ihren Implementierungsanforderungen.
Tags und Links c++ c++11 pointers function-pointers