suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen
-
Nathan schrieb:
Kannst du mal ein/zwei Funktionen vereinfacht zeigen, damit man sieht, wie das aussieht?
Ja. So etwa könnte das aussehen:
void fuellen_1(array& a, const int n,const double alpha) { double x=anfang; for(int i=0;i<n;i++) { a[i] = tolle_math_funktion_99(i,x,alpha); x += 1; } } void fuellen_2(array& a, const int n, const double alpha, const double beta) { double x=anfang; for(int i=0;i<n;i++) { a[i] = tolle_math_funktion_79(i,x,alpha,beta); x += 1; } }Nicht besonders spannend. Was tolle_math_funktion_99 usw. darstellt, ist für die Problemstellung unerheblich. Ich möchte Ähnliches unter einen Hut bringen, so wenig wie möglich wiederholen (und später vielleicht ändern müssen). Leider ist schon die Signatur der Funktionen von drei verschiedenen Arten.
Bisher habe ich die Schleife 3x programmiert, innen wird dann ein Funktionspointer aufgerufen.
LG
wastl
-
Nexus schrieb:
STL-Algorithmen wie
std::fill()oderstd::generate()könnten helfen.Aha. fill() füllt aber nur mit Konstanten, das
ist math. nicht sinnvoll für meine Problemstellung.
generate() ist besser, es wird eleganter, aber das
Problem verschiebt sich nun auf einen Sack von
Funktionspointern oder Funktoren.
generate() sollte auch mit Lamdas gehen, oder?Vielleicht ist es für den User hinterher einfacher,
wenn ich eine Klasse schreibe, aus deren Deklaration
(z.B. mit Enum) schon hervorgeht, welche Fenster
verfügbar sind.LG
wastl
-
Nexus schrieb:
Brich die Zeilen nicht manuell um, das ist äusserst mühsam zu lesen.

Und lies auch den Tipp bezüglich CV-Qualifizierer. Zudem frage ich mich, wie du ein konstantes Array überhaupt verändern willst, aber das ist wahrscheinlich nur ein Fehler im Minimalbeispiel...
Mit
std::bind()kannst du bestehende Funktionen und ihre Argumente zusammenbinden. Das geht sehr gut bei Konstanten, bei einem veränderbarenxbzw.iwirds etwas schwieriger. Wie siehts hier aus? Kannst du konkretisieren, welcher Teil der Signatur bei den mathematischen Funktionen immer gleich bleibt? Werden diexundiimmer übergeben?
-
[quote="Nexus"]
Nexus schrieb:
Und lies auch den Tipp bezüglich CV-Qualifizierer. Zudem frage ich mich, wie du ein konstantes Array überhaupt verändern willst, aber das ist wahrscheinlich nur ein Fehler im Minimalbeispiel...
ja, das ist natürlich Blödsinn, ich ändere das
-
Nexus schrieb:
Nexus schrieb:
Brich die Zeilen nicht manuell um, das ist äusserst mühsam zu lesen.

Ach so, gemeint ist der normale Text, ich dachte, warum will er denn so lange Programmzeilen?

-
Nexus schrieb:
Mit
std::bind()kannst du bestehende Funktionen und ihre Argumente zusammenbinden. Das geht sehr gut bei Konstanten, bei einem veränderbarenxbzw.iwirds etwas schwieriger. Wie siehts hier aus? Kannst du konkretisieren, welcher Teil der Signatur bei den mathematischen Funktionen immer gleich bleibt? Werden diexundiimmer übergeben?Das sieht interessant aus. Ich kann immer einen Wrapper für solche Funktionen schreiben, der konstante Argumente hat udn wenn ich sie in einen Funktor kleiden muss, damit ich einen internen Zustand mir merken kann. Ich schaue es mir genauer an.
-
Ich denke auch dass
std::generatehier angebracht wäre.
Statt einem Haufen "Fill-Funktionen" schreibst du dann einfach einen Haufen Generatoren.Bzw. einen Generator, der im Konstruktor einen Funktor mitgegeben bekommt, und diesen mit dem nötigen "x" aufruft.
Und den Funktor kannst du dann mitbind()erzeugen.
-
void fuellen_1(array& a, const int n, const double alpha) { double x = anfang; for(int i = 0; i < n; i++) { a[i] = tolle_math_funktion_99(i, x, alpha); x += 1; } } void fuellen_2(array& a, const int n, const double alpha, const double beta) { double x = anfang; for(int i = 0; i < n; i++) { a[i] = tolle_math_funktion_79(i, x, alpha, beta); x += 1; } }
-
ja, ich nehme sonst immer astyle. Sollte ich vorher drüber laufen lassen.

-
wastl schrieb:
Ja. So etwa könnte das aussehen:
void fuellen_1(array& a, const int n,const double alpha) { double x=anfang; for(int i=0;i<n;i++) { a[i] = tolle_math_funktion_99(i,x,alpha); x += 1; } } void fuellen_2(array& a, const int n, const double alpha, const double beta) { double x=anfang; for(int i=0;i<n;i++) { a[i] = tolle_math_funktion_79(i,x,alpha,beta); x += 1; } }Nicht besonders spannend. Was tolle_math_funktion_99 usw. darstellt, ist für die Problemstellung unerheblich. Ich möchte Ähnliches unter einen Hut bringen, so wenig wie möglich wiederholen (und später vielleicht ändern müssen). Leider ist schon die Signatur der Funktionen von drei verschiedenen Arten.
Bisher habe ich die Schleife 3x programmiert, innen wird dann ein Funktionspointer aufgerufen.
Weder array noch anfang waren spezifiziert. Hab da improvisiert.
Erstmal zur Unterhaltung ein wenig 80-er-Jahre-Code:
double soeinfenster(int i,double x,double,double) { return x; } double anderesfenster(int i,double x,double alpha,double beta) { return x+alpha+beta; } void fuellen(double* a,int n,double(*func)(int,double,double,double),double alpha=0,double beta=0) { double x=0; for(int i=0; i<n; i++) { a[i] = func(i,x,alpha,beta); x += 1; } } int main() { double arr[10]; fuellen(arr,10,soeinfenster); fuellen(arr,10,anderesfenster,2.71,3.14); fuellen(arr,10,anderesfenster,2.71);//kein compilerfehler! // fuellen(arr,10,[](int i,double x,double,double){return 1;});//nö }Kannst die Lamdas schon mißbrauchen, um "Parameter" nach unten durchzureichen:
template<typename FUNC> void fuellen(double* a,int n,FUNC func) { double x=0; for(int i=0; i<n; i++) { a[i] = func(i,x); x += 1; } } int main() { double arr[10]; fuellen(arr,10, [](int i,double x) {//soeinfenster return x; }); double alpha=2,beta=3; fuellen(arr,10, [alpha,beta](int i,double x) {//anderesfenster return x+alpha+beta; }); }Aber der Code macht mich ein Bißchen traurig. Irgendwie drückt er Deine Füll-Funktionen nicht aus. Generatoren würden es eigentlich ausdrücken, aber die sind so unlogisch zu implementieren irgendwie, man muss tricksen, um Schleifen hinzubekommen, die man viel leichter direkt schreiben könnte. Und bind fällt bei mir gleich aus jeder Betrachtung. Bleiben also nur noch gute alte Makros übrig, um die drei Funktionen zu vereinheitlichen. Hihi, wem ist gerade vor Schreck die Kaffetasse aus der Hand gerutscht?
double soeinfenster(int i,double x) { return x; } double anderesfenster(int i,double x,double alpha,double beta) { return x+alpha+beta; } template<typename FUNC,typename... ARGS> void fuellen(double* a,int n,FUNC func,ARGS... args) { double x=0; for(int i=0; i<n; i++) { a[i] = func(i,x,args...); x += 1; } } int main() { double arr[10]; fuellen(arr,10,soeinfenster); fuellen(arr,10,anderesfenster,2.71,3.14); // fuellen(arr,10,anderesfenster,2.71);//compilerfehler fuellen(arr,10,[](int i,double x){return 1;});//naja, wer's mag... }