C ++: Übergabefunktion mit beliebig vielen Parametern als Parameter

Langzeitbrowser, erstmaliger Fragesteller hier. 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 hinsichtlich der Integrationsmöglichkeiten so flexibel wie möglich ist.

Hier ein Beispiel: Ein sehr einfaches Beispiel für eine Trapezregel, bei dem ich einen Zeiger auf die zu integrierende Funktion übergebe.

// Numerically integrate (*f) from a to b
// using the trapezoidal rule.
double trap(double (*f)(double), double a, double b) {
  int N = 10000;
  double step = (b-a)/N;
  double s = 0;
  for (int i=0; i<=N; i++) {
    double xi = a + i*step;
    if (i == 0 || i == N) { s += (*f)(xi); }
    else { s += 2*(*f)(xi); }
  }
  s *= (b-a)/(2*N);
  return s;
}

Dies funktioniert hervorragend für einfache Funktionen, die nur ein Argument enthalten. Beispiel:

double a = trap(sin,0,1);

Manchmal möchte ich jedoch möglicherweise etwas integrieren, das mehr Parameter aufweist, z. B. ein quadratisches Polynom. In diesem Beispiel werden die Koeffizienten vor der Integration vom Benutzer definiert. Beispielcode:

// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
  return (A*pow(x,2) + B*x + C);
}

Idealerweise könnte ich so etwas tun, um es zu integrieren:

double b = trap(quad(1,2,3),0,1);

Aber das funktioniert natürlich nicht. Ich habe dieses Problem umgangen, indem ich eine Klasse definiert habe, die die Koeffizienten als Mitglieder und die Funktion von Interesse als Mitgliederfunktion hat:

class Model {
  double A,B,C;
public:
  Model() { A = 0; B = 0; C = 0; }
  Model(double x, double y, double z) { A = x; B = y; C = z; }
  double func(double x) { return (A*pow(x,2)+B*x+C); }
};

Dann muss sich jedoch meine Integrationsfunktion ändern, um ein Objekt anstelle eines Funktionszeigers als Eingabe zu verwenden:

// Numerically integrate model.func from a to b
// using the trapezoidal rule.
double trap(Model poly, double a, double b) {
  int N = 10000;
  double step = (b-a)/N;
  double s = 0;
  for (int i=0; i<=N; i++) {
    double xi = a + i*step;
    if (i == 0 || i == N) { s += poly.func(xi); }
    else { s += 2*poly.func(xi); }
  }
  s *= (b-a)/(2*N);
  return s;
}

Dies funktioniert gut, aber die resultierende Bibliothek ist nicht sehr unabhängig, da die Klasse Model irgendwo definiert werden muss. Idealerweise sollte sich das Modell auch von Benutzer zu Benutzer ändern lassen, damit ich es nicht in einer Header-Datei reparieren möchte. Ich habe versucht, Funktionsvorlagen und Funktoren zu verwenden, um dies zum Laufen zu bringen, aber es ist nicht sehr unabhängig, da die Vorlage wieder in einer Header-Datei definiert werden sollte (es sei denn, Sie möchten explizit instanziieren, was ich nicht will).

Zusammenfassend lässt sich sagen, ob ich meine Integrationsfunktionen auf irgendeine Weise dazu bringen kann, beliebige 1D-Funktionen mit einer variablen Anzahl von Eingabeparametern zu akzeptieren und dabei unabhängig genug zu bleiben, damit sie zu einer eigenständigen Bibliothek kompiliert werden können. Vielen Dank im Voraus für die Vorschläge.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage