<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen]]></title><description><![CDATA[<p>Hallo,<br />
ich suche eine elegante Lösung für eine Vielzahl ähnlicher Funktionen. Ich habe ein Array bzw. Vector, der/das mit Zahlen gefüllt werden soll.<br />
Dies erfolgt nach einigen Dutzend verschiedener math. Algorithmen. Alle rauchen die Länge des Array als Parameter (bei einem Vector wäre das natürlich nicht explizit nötig). Dazu kann noch ein zweiter und auch ggf. ein dritter math. Parameter kommen.<br />
Jetzt kann man das natürlich einfach als eine Vielzahl von Funktionen nach folgendem Schema lösen:</p>
<pre><code>void fuellen_1(array&amp; a, int n);
void fuellen_1a(array&amp; a, int n);
void fuellen_1c(array&amp; a, int n);
void fuellen_2(array&amp; a, int n, double alpha);
void fuellen_2a(array&amp; a, int n, double alpha);
void fuellen_2b(array&amp; a, int n, double alpha);
void fuellen_3(array&amp; a, int n, double alpha, double beta);
void fuellen_3a(array&amp; a, int n, double alpha, double beta);
void fuellen_3b(array&amp; a, int n, double alpha, double beta);
...
...
</code></pre>
<p>Dabei fällt auf, dass diese Funktionen natürlich sehr viel Code gemeinsam aben, z.B. eine Schleife über die Länge des Array usw. Man sollte vermeiden, immer das selbe wieder und wieder zu programmieren.<br />
Man merkt am Beispiel schon, was für ein Zoo das wird und wie nervig. Die math. Prozedur der Funktionen wird darüber hinaus nirgends sonst im Programm gebraucht, bzw. soll nicht benutzt werden, nur über das gebotene Interface.<br />
Anonymität ist also kein Problem. Die Laufzeit ist nicht sehr kritisch, die Programmlaufzeit wird durch andere Funktionalitäten bestimmt.</p>
<p>Man könnte Pointer auf Funktionen verwenden.<br />
Oder static Funktionen.<br />
Oder Funktoren.<br />
Oder Lambdas.<br />
Oder eine Klasse, bei der man die Art der Funktion (als Member) auswählt und dann füllen lässt...</p>
<p>Was wäre aber eine elegante Lösung?</p>
<p>Mit Dank für gute Ratschläge<br />
wastl</p>
<p>p.s.: math. geht es um sog. Fenster-Funktionen, aus den unendlich vielen Möglichkeiten sind ca. 3 - 4 Dutzend populär, z.B. Kaiser-, Gauß-, Hanning-, Hamming-, Dolph-Fenster, usw. usw., manche sind höchst simpel, andere gehen in ihrer Theorie deutlich über die ersten Semester eines math.<br />
Diplomstudiums hinaus ...</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/322578/suche-elegante-lösung-für-mehrere-ähnliche-wiederholte-funktionen</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Jul 2026 01:49:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/322578.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 29 Dec 2013 17:51:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 21:11:55 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich suche eine elegante Lösung für eine Vielzahl ähnlicher Funktionen. Ich habe ein Array bzw. Vector, der/das mit Zahlen gefüllt werden soll.<br />
Dies erfolgt nach einigen Dutzend verschiedener math. Algorithmen. Alle rauchen die Länge des Array als Parameter (bei einem Vector wäre das natürlich nicht explizit nötig). Dazu kann noch ein zweiter und auch ggf. ein dritter math. Parameter kommen.<br />
Jetzt kann man das natürlich einfach als eine Vielzahl von Funktionen nach folgendem Schema lösen:</p>
<pre><code>void fuellen_1(array&amp; a, int n);
void fuellen_1a(array&amp; a, int n);
void fuellen_1c(array&amp; a, int n);
void fuellen_2(array&amp; a, int n, double alpha);
void fuellen_2a(array&amp; a, int n, double alpha);
void fuellen_2b(array&amp; a, int n, double alpha);
void fuellen_3(array&amp; a, int n, double alpha, double beta);
void fuellen_3a(array&amp; a, int n, double alpha, double beta);
void fuellen_3b(array&amp; a, int n, double alpha, double beta);
...
...
</code></pre>
<p>Dabei fällt auf, dass diese Funktionen natürlich sehr viel Code gemeinsam aben, z.B. eine Schleife über die Länge des Array usw. Man sollte vermeiden, immer das selbe wieder und wieder zu programmieren.<br />
Man merkt am Beispiel schon, was für ein Zoo das wird und wie nervig. Die math. Prozedur der Funktionen wird darüber hinaus nirgends sonst im Programm gebraucht, bzw. soll nicht benutzt werden, nur über das gebotene Interface.<br />
Anonymität ist also kein Problem. Die Laufzeit ist nicht sehr kritisch, die Programmlaufzeit wird durch andere Funktionalitäten bestimmt.</p>
<p>Man könnte Pointer auf Funktionen verwenden.<br />
Oder static Funktionen.<br />
Oder Funktoren.<br />
Oder Lambdas.<br />
Oder eine Klasse, bei der man die Art der Funktion (als Member) auswählt und dann füllen lässt...</p>
<p>Was wäre aber eine elegante Lösung?</p>
<p>Mit Dank für gute Ratschläge<br />
wastl</p>
<p>p.s.: math. geht es um sog. Fenster-Funktionen, aus den unendlich vielen Möglichkeiten sind ca. 3 - 4 Dutzend populär, z.B. Kaiser-, Gauß-, Hanning-, Hamming-, Dolph-Fenster, usw. usw., manche sind höchst simpel, andere gehen in ihrer Theorie deutlich über die ersten Semester eines math.<br />
Diplomstudiums hinaus ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374013</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374013</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 21:11:55 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 17:58:13 GMT]]></title><description><![CDATA[<p>Kannst du mal ein/zwei Funktionen vereinfacht zeigen, damit man sieht, wie das aussieht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374015</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374015</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sun, 29 Dec 2013 17:58:13 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 18:08:14 GMT]]></title><description><![CDATA[<p>STL-Algorithmen wie <code>std::fill()</code> oder <code>std::generate()</code> könnten helfen.</p>
<p>Und bitte lass die unnötigen <code>const</code> weg. Wenn du sie in der Definition umbedingt brauchst, ist das eine Sache, aber in der Deklaration haben Top-Level-CV-Qualifizierer nichts verloren. Du gibst dem Aufrufer damit keine brauchbare Information, sondern verwirrst nur.</p>
<pre><code>void funktion(const T* param);  // ok
void funktion(const T&amp; param);  // ok
void funktion(const T param);   // unnötig
</code></pre>
<p>Noch was: Brich die Zeilen nicht manuell um, das ist äusserst mühsam zu lesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374016</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 29 Dec 2013 18:08:14 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 21:13:14 GMT]]></title><description><![CDATA[<p>Nathan schrieb:</p>
<blockquote>
<p>Kannst du mal ein/zwei Funktionen vereinfacht zeigen, damit man sieht, wie das aussieht?</p>
</blockquote>
<p>Ja. So etwa könnte das aussehen:</p>
<pre><code>void fuellen_1(array&amp; a, const int n,const double alpha)
  {
  double x=anfang;
  for(int i=0;i&lt;n;i++)
    {
    a[i] = tolle_math_funktion_99(i,x,alpha);
    x += 1;
    }
  }

void fuellen_2(array&amp; a, const int n, const double alpha, const double beta)
  {
  double x=anfang;
  for(int i=0;i&lt;n;i++)
    {
    a[i] = tolle_math_funktion_79(i,x,alpha,beta);
    x += 1;
    }
  }
</code></pre>
<p>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.</p>
<p>Bisher habe ich die Schleife 3x programmiert, innen wird dann ein Funktionspointer aufgerufen.</p>
<p>LG<br />
wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374018</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 21:13:14 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 18:21:03 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>STL-Algorithmen wie <code>std::fill()</code> oder <code>std::generate()</code> könnten helfen.</p>
</blockquote>
<p>Aha. fill() füllt aber nur mit Konstanten, das<br />
ist math. nicht sinnvoll für meine Problemstellung.<br />
generate() ist besser, es wird eleganter, aber das<br />
Problem verschiebt sich nun auf einen Sack von<br />
Funktionspointern oder Funktoren.<br />
generate() sollte auch mit Lamdas gehen, oder?</p>
<p>Vielleicht ist es für den User hinterher einfacher,<br />
wenn ich eine Klasse schreibe, aus deren Deklaration<br />
(z.B. mit Enum) schon hervorgeht, welche Fenster<br />
verfügbar sind.</p>
<p>LG<br />
wastl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374019</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 18:21:03 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 19:00:27 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p><strong>Brich die Zeilen nicht manuell um, das ist äusserst mühsam zu lesen.</strong></p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
<p>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...</p>
<p>Mit <code>std::bind()</code> kannst du bestehende Funktionen und ihre Argumente zusammenbinden. Das geht sehr gut bei Konstanten, bei einem veränderbaren <code>x</code> bzw. <code>i</code> wirds etwas schwieriger. Wie siehts hier aus? Kannst du konkretisieren, welcher Teil der Signatur bei den mathematischen Funktionen immer gleich bleibt? Werden die <code>x</code> und <code>i</code> immer übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374021</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374021</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 29 Dec 2013 19:00:27 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 21:05:06 GMT]]></title><description><![CDATA[<p>[quote=&quot;Nexus&quot;]</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>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...</p>
</blockquote>
<p>ja, das ist natürlich Blödsinn, ich ändere das</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374037</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374037</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 21:05:06 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 21:17:37 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p><strong>Brich die Zeilen nicht manuell um, das ist äusserst mühsam zu lesen.</strong></p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
</blockquote>
<p>Ach so, gemeint ist der normale Text, ich dachte, warum will er denn so lange Programmzeilen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374042</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374042</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 21:17:37 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Sun, 29 Dec 2013 21:19:26 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Mit <code>std::bind()</code> kannst du bestehende Funktionen und ihre Argumente zusammenbinden. Das geht sehr gut bei Konstanten, bei einem veränderbaren <code>x</code> bzw. <code>i</code> wirds etwas schwieriger. Wie siehts hier aus? Kannst du konkretisieren, welcher Teil der Signatur bei den mathematischen Funktionen immer gleich bleibt? Werden die <code>x</code> und <code>i</code> immer übergeben?</p>
</blockquote>
<p>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.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374043</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374043</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Sun, 29 Dec 2013 21:19:26 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Mon, 30 Dec 2013 03:57:34 GMT]]></title><description><![CDATA[<p>Ich denke auch dass <code>std::generate</code> hier angebracht wäre.<br />
Statt einem Haufen &quot;Fill-Funktionen&quot; schreibst du dann einfach einen Haufen Generatoren.</p>
<p>Bzw. einen Generator, der im Konstruktor einen Funktor mitgegeben bekommt, und diesen mit dem nötigen &quot;x&quot; aufruft.<br />
Und den Funktor kannst du dann mit <code>bind()</code> erzeugen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374071</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374071</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 30 Dec 2013 03:57:34 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Mon, 30 Dec 2013 09:42:05 GMT]]></title><description><![CDATA[<ul>
<li></li>
</ul>
<pre><code>void fuellen_1(array&amp; a, const int n, const double alpha)
{
    double x = anfang;
    for(int i = 0; i &lt; n; i++)
    {
        a[i] = tolle_math_funktion_99(i, x, alpha);
        x += 1;
    }
}

void fuellen_2(array&amp; a, const int n, const double alpha, const double beta)
{
    double x = anfang;
    for(int i = 0; i &lt; n; i++)
    {
        a[i] = tolle_math_funktion_79(i, x, alpha, beta);
        x += 1;
    }
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2374079</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374079</guid><dc:creator><![CDATA[hardware]]></dc:creator><pubDate>Mon, 30 Dec 2013 09:42:05 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Mon, 30 Dec 2013 09:52:55 GMT]]></title><description><![CDATA[<p>ja, ich nehme sonst immer astyle. Sollte ich vorher drüber laufen lassen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f4a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--light_bulb"
      title=":bulb:"
      alt="💡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374080</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374080</guid><dc:creator><![CDATA[wastl]]></dc:creator><pubDate>Mon, 30 Dec 2013 09:52:55 GMT</pubDate></item><item><title><![CDATA[Reply to suche elegante Lösung für mehrere ähnliche, wiederholte Funktionen on Mon, 30 Dec 2013 17:22:12 GMT]]></title><description><![CDATA[<p>wastl schrieb:</p>
<blockquote>
<p>Ja. So etwa könnte das aussehen:</p>
<pre><code>void fuellen_1(array&amp; a, const int n,const double alpha)
  {
  double x=anfang;
  for(int i=0;i&lt;n;i++)
    {
    a[i] = tolle_math_funktion_99(i,x,alpha);
    x += 1;
    }
  }

void fuellen_2(array&amp; a, const int n, const double alpha, const double beta)
  {
  double x=anfang;
  for(int i=0;i&lt;n;i++)
    {
    a[i] = tolle_math_funktion_79(i,x,alpha,beta);
    x += 1;
    }
  }
</code></pre>
<p>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.</p>
<p>Bisher habe ich die Schleife 3x programmiert, innen wird dann ein Funktionspointer aufgerufen.</p>
</blockquote>
<p>Weder array noch anfang waren spezifiziert. Hab da improvisiert.</p>
<p>Erstmal zur Unterhaltung ein wenig 80-er-Jahre-Code:</p>
<pre><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&lt;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ö
}
</code></pre>
<p>Kannst die Lamdas schon mißbrauchen, um &quot;Parameter&quot; nach unten durchzureichen:</p>
<pre><code>template&lt;typename FUNC&gt;
void fuellen(double* a,int n,FUNC func)
{
    double x=0;
    for(int i=0; i&lt;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;
    });
}
</code></pre>
<p>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?</p>
<pre><code>double soeinfenster(int i,double x)
{
    return x;
}
double anderesfenster(int i,double x,double alpha,double beta)
{
    return x+alpha+beta;
}

template&lt;typename FUNC,typename... ARGS&gt;
void fuellen(double* a,int n,FUNC func,ARGS... args)
{
    double x=0;
    for(int i=0; i&lt;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...
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2374152</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374152</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 30 Dec 2013 17:22:12 GMT</pubDate></item></channel></rss>