lange Zeit Browser, erste Zeit hier fragen. Ich habe eine Reihe von Skripten für verschiedene numerische 1D-Integrationsmethoden geschrieben und diese in eine Bibliothek kompiliert. Ich möchte, dass diese Bibliothek so flexibel wie möglich ist, was sie integrieren kann.
Hier ein Beispiel: ein sehr einfaches trapezförmiges Regelbeispiel, bei dem ich einen Zeiger auf die zu integrierende Funktion übergebe.
%Vor%Dies funktioniert hervorragend für einfache Funktionen, die nur ein Argument benötigen. Beispiel:
%Vor%Manchmal möchte ich jedoch etwas integrieren, das mehr Parameter hat, wie ein quadratisches Polynom. In diesem Beispiel würden die Koeffizienten vor der Integration vom Benutzer definiert werden. Beispielcode:
%Vor%Idealerweise wäre ich in der Lage, so etwas zu tun, um es zu integrieren:
%Vor%Aber klar, das geht nicht. Ich habe dieses Problem umgangen, indem ich eine Klasse definiert habe, die die Koeffizienten als Elemente und die interessierende Funktion als Elementfunktion hat:
%Vor%Allerdings muss sich meine Integrationsfunktion ändern, um ein Objekt als Eingabe anstelle eines Funktionszeigers zu verwenden:
%Vor%Das funktioniert gut, aber die resultierende Bibliothek ist nicht sehr unabhängig, da sie die Klasse Model benötigt, die irgendwo definiert werden soll. Außerdem sollte das Model im Idealfall von Benutzer zu Benutzer wechseln können, so dass ich es nicht in einer Header-Datei reparieren möchte. Ich habe versucht, Funktionsvorlagen und Funktoren zu verwenden, um dies zum Funktionieren zu bringen, aber es ist nicht sehr unabhängig, da die Vorlage wiederum in einer Header-Datei definiert werden sollte (es sei denn, Sie möchten explizit instanziieren, was ich nicht) >
Um es kurz zu fassen: Gibt es irgendeine Möglichkeit, meine Integrationsfunktionen dazu zu bringen, beliebige 1D-Funktionen mit einer variablen Anzahl von Eingabeparametern zu akzeptieren und gleichzeitig unabhängig genug zu bleiben, damit sie in eine eigenständige Bibliothek kompiliert werden können? Vielen Dank im Voraus für die Vorschläge.
Was Sie brauchen, sind Vorlagen und std::bind()
(oder sein boost::bind()
Gegenstück, wenn Sie sich C ++ 11 nicht leisten können). Zum Beispiel ist dies Ihre trap()
Funktion:
Beachten Sie, dass wir von Funktionszeigern verallgemeinern und zulassen, dass jeder Typ von aufrufbaren Objekten (einschließlich eines C ++ - 11-Lambdas) übergeben wird. Daher muss die Syntax zum Aufrufen des Vom Benutzer bereitgestellte Funktion ist nicht *f(param)
(was nur für Funktionszeiger funktioniert), sondern nur f(param)
.
In Bezug auf die Flexibilität betrachten wir zwei fest codierte Funktionen (und tun so, als wären sie sinnvoll):
%Vor% Sie können nun sowohl die erste Funktion direkt in trap()
eingeben, als auch das Ergebnis der Bindung der letzten drei Argumente der zweiten Funktion an einen bestimmten Wert (Sie haben freie Wahl, welche Argumente zu binden sind):
Natürlich können Sie mit lambdas noch mehr Flexibilität erhalten:
%Vor% Und Sie können auch Ihre eigenen statusfähigen Funktoren an tp trap()
oder einige aufrufbare Objekte übergeben, die in ein std::function
-Objekt eingewickelt sind (oder boost::function
, wenn Sie sich C ++ 11 nicht leisten können). Die Auswahl ist ziemlich breit.
Hier ist ein Live-Beispiel .
Was Sie versuchen, ist, dies möglich zu machen
%Vor%Mit C ++ 11 haben wir Alias-Template und Variadic-Template
%Vor% oben definiert eine custom_function_t
, die eine doppelte und variable Anzahl von Argumenten benötigt.
, damit Ihre Funktion trap
Verwendung:
%Vor%Getestet auf Apple LLVM 4.2 Compiler.
Tags und Links c++ templates function-pointers functor