<?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[Varadic Templates und funktionale Programmierung]]></title><description><![CDATA[<p>Ich will die Moeglichkeiten der funktionalen Programmierung mittels Templates ausloten. Dazu keine kleine List:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;

template &lt;int I&gt; using int_ = std::integral_constant&lt;int, I&gt;;

template&lt;typename T&gt; using eval = typename T::result;

template&lt;typename S&gt; using car = typename S::car;
template&lt;typename S&gt; using cdr = typename S::cdr;

template&lt;typename... List&gt;
struct seq;

template&lt;typename Car, typename... Cdr&gt;
struct seq_car
{
    typedef Car car;
};

template&lt;typename Car, typename... Cdr&gt;
struct seq_cdr
{
    typename typedef seq&lt;Cdr...&gt; cdr;
};

template&lt;typename... List&gt;
struct seq
{
    static const unsigned length = sizeof...(List);
    typename typedef seq_car&lt;List...&gt; car;
    typename typedef seq_cdr&lt;List...&gt;::cdr cdr;
};

template&lt;&gt;
struct seq&lt;&gt;
{
    static const unsigned length = 0;
};

int main()
{
    typedef seq&lt;int_&lt;1&gt;, int_&lt;2&gt;, int_&lt;3&gt; &gt; s;
    std::cerr &lt;&lt; cdr&lt;s&gt;::length &lt;&lt; '\n';

    return 0;
}
</code></pre>
<p>Nun moechte ich mittels cons (siehe Scheme) Listen aufbauen. Ich suche also einen Typ(konstruktor) der ein Element an den Kopf der Listen anhaengt. Wie realisieren?<br />
Beispiel:</p>
<pre><code>cons&lt; 1, seq&lt;1, 2, 3&gt; &gt;::result -&gt; seq&lt;1, 1, 2, 3&gt;
</code></pre>
<p>Meine leise Vermutung ist, dass es ebenfalls nicht funktioniert und ich auf Tupel mit Vererbung ausweichen muss oder aber wie auch in Scheme durch std::pair&lt;Head, Tail&gt; aufbauen.</p>
<p>Natuerlich ist das nur der erste Schritt, nachfolgend sollen map, fold, filter implementiert werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/320705/varadic-templates-und-funktionale-programmierung</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Jul 2026 01:13:09 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/320705.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 08 Oct 2013 15:33:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 15:36:58 GMT]]></title><description><![CDATA[<p>Ich will die Moeglichkeiten der funktionalen Programmierung mittels Templates ausloten. Dazu keine kleine List:</p>
<pre><code class="language-cpp">#include &lt;type_traits&gt;

template &lt;int I&gt; using int_ = std::integral_constant&lt;int, I&gt;;

template&lt;typename T&gt; using eval = typename T::result;

template&lt;typename S&gt; using car = typename S::car;
template&lt;typename S&gt; using cdr = typename S::cdr;

template&lt;typename... List&gt;
struct seq;

template&lt;typename Car, typename... Cdr&gt;
struct seq_car
{
    typedef Car car;
};

template&lt;typename Car, typename... Cdr&gt;
struct seq_cdr
{
    typename typedef seq&lt;Cdr...&gt; cdr;
};

template&lt;typename... List&gt;
struct seq
{
    static const unsigned length = sizeof...(List);
    typename typedef seq_car&lt;List...&gt; car;
    typename typedef seq_cdr&lt;List...&gt;::cdr cdr;
};

template&lt;&gt;
struct seq&lt;&gt;
{
    static const unsigned length = 0;
};

int main()
{
    typedef seq&lt;int_&lt;1&gt;, int_&lt;2&gt;, int_&lt;3&gt; &gt; s;
    std::cerr &lt;&lt; cdr&lt;s&gt;::length &lt;&lt; '\n';

    return 0;
}
</code></pre>
<p>Nun moechte ich mittels cons (siehe Scheme) Listen aufbauen. Ich suche also einen Typ(konstruktor) der ein Element an den Kopf der Listen anhaengt. Wie realisieren?<br />
Beispiel:</p>
<pre><code>cons&lt; 1, seq&lt;1, 2, 3&gt; &gt;::result -&gt; seq&lt;1, 1, 2, 3&gt;
</code></pre>
<p>Meine leise Vermutung ist, dass es ebenfalls nicht funktioniert und ich auf Tupel mit Vererbung ausweichen muss oder aber wie auch in Scheme durch std::pair&lt;Head, Tail&gt; aufbauen.</p>
<p>Natuerlich ist das nur der erste Schritt, nachfolgend sollen map, fold, filter implementiert werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358928</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358928</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 08 Oct 2013 15:36:58 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 15:39:04 GMT]]></title><description><![CDATA[<p>Schau mal da: <a href="http://www.c-plusplus.net/forum/p2286465#2286465" rel="nofollow">http://www.c-plusplus.net/forum/p2286465#2286465</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358931</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358931</guid><dc:creator><![CDATA[mapfold]]></dc:creator><pubDate>Tue, 08 Oct 2013 15:39:04 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 15:45:57 GMT]]></title><description><![CDATA[<p>Danke, da ich Vollnoob bin und das verstehen will, gibt es eine gute Einfuehrung in variadic templates, die nicht bei den trivialen Sachen aufhoert? Going Native 2012 und &quot;Variadic Templates are Funadic&quot; steht schon auf meiner Liste.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358932</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358932</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 08 Oct 2013 15:45:57 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 15:50:29 GMT]]></title><description><![CDATA[<pre><code>template &lt;typename, typename&gt;
struct cons;

template &lt;typename T, typename... L&gt;
struct cons&lt;T, seq&lt;L...&gt;&gt;
{
    typedef seq&lt;T, L...&gt; type;
};
</code></pre>
<p>Sowas?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358934</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358934</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Tue, 08 Oct 2013 15:50:29 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 15:54:23 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Danke, da ich Vollnoob bin und das verstehen will, gibt es eine gute Einfuehrung in variadic templates, die nicht bei den trivialen Sachen aufhoert?</p>
</blockquote>
<p>Nicht soweit ich weiß. camper sollte vielleicht mal ein kleines Tutorial schreiben, leider hat er für so etwas keine Zeit...</p>
<pre><code>template&lt;typename... List&gt;
struct seq
{
	static const unsigned length = sizeof...(List);
	typedef seq_car&lt;List...&gt; car;
	typedef typename seq_cdr&lt;List...&gt;::cdr cdr;

	using type = seq; // Eine nützliche Konvention
};

template&lt;typename, typename&gt; struct cons;

template&lt;typename... s, typename to_append&gt;
struct cons&lt;seq&lt;s...&gt;, to_append&gt; :
	seq&lt;to_append, s...&gt; {};

#include &lt;iostream&gt;
int main()
{
	typedef seq&lt;int_&lt;1&gt;, int_&lt;2&gt;, int_&lt;3&gt;&gt; s;

	using new_s = cons&lt;s, int_&lt;1&gt;&gt;::type;

	std::cout &lt;&lt; new_s::length &lt;&lt; '\n';
}
</code></pre>
<p>Alternativ kannst du auch eine concat-Funktion schreiben.<br />
Ich habe übrigens eine kleine Lib mit solchen Funktionen geschrieben, <a href="https://github.com/bingojamigo/VTMPL" rel="nofollow">VTMPL</a>. (Ohne maps o.ä., nur fundamentalere Sachen)</p>
<p>P.S.: Hast du den Code eigentlich mal getestet?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358935</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 08 Oct 2013 15:54:23 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 16:03:20 GMT]]></title><description><![CDATA[<p>Also ich habe jetzt den Code von Kellerautomat genommen und er funktioniert wie erwartet.</p>
<pre><code class="language-cpp">template &lt;typename T, typename... L&gt;
struct cons&lt;T, seq&lt;L...&gt;&gt;
</code></pre>
<p>Wohoo, magic. Sowas aehnliches hatte ich auch schon mal, leider ohne Vorwaertsdeklaration.</p>
<blockquote>
<p>P.S.: Hast du den Code eigentlich mal getestet?</p>
</blockquote>
<p>Nur Kellerautomats Code bis jetzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358936</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358936</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 08 Oct 2013 16:03:20 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 16:17:33 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<blockquote>
<p>P.S.: Hast du den Code eigentlich mal getestet?</p>
</blockquote>
<p>Nur Kellerautomats Code bis jetzt.</p>
</blockquote>
<p>Ja, denn dein Post aus dem OP ist völliger Unsinn.</p>
<pre><code>typename typedef seq_car&lt;List...&gt; car;
</code></pre>
<p>? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<blockquote>
<p>Wohoo, magic. Sowas aehnliches hatte ich auch schon mal, leider ohne Vorwaertsdeklaration.</p>
</blockquote>
<p>Das ist eine Spezialisierung, und ohne Primärtemplate ist das auch nicht erlaubt. Daher sieht in TMP der Code meistens so aus:</p>
<p>Primärtemplate, kein vollständiger Typ<br />
Spezialisierung für den gewünschten Typ, bspw. Typliste<br />
ggf. Weitere Spezialisierungen<br />
ggf. Eine Spezialisierung die die Rekursion unterbricht und einen Endfall definiert; Diese leitet dann vom &quot;Rückgabetyp&quot; ab.</p>
<p>Daher ist es Konvention, allen Typen einen Typedef mit sich selbst reinzustecken, damit man dann später auf den Basisklassentyp, von dem die letzte Spezialisierung ableitet, zugreifen kann.</p>
<p>Besonders elegant sind daher die Konstrukte, die 1. keine Spezialisierung benötigen (da kürzer) 2. Ohne Template-Rekursion auskommen (das hat, wie camper schon einmal erklärt hat, gute Gründe!).</p>
<p>Besonders nützlich für letzteres sind Arrays mit den Werten in der Werte-Klasse. Da kann man superschnell und mit O(1) auf die Elemente der Liste zugreifen. Meine Lib macht es genauso.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358939</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358939</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 08 Oct 2013 16:17:33 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 16:30:00 GMT]]></title><description><![CDATA[<blockquote>
<p>Ja, denn dein Post aus dem OP ist völliger Unsinn.</p>
</blockquote>
<p>Also er funktioniert, bzw. wird von VS 2013 compiliert und ausgefuehrt. Er macht, das was er soll, die zusaetzlichen Indirektionen sind wahrscheinlich nicht noetig bei der neuen Magie. Die Zahlen kannst du gern durch int_&lt;n&gt; ersetzen.</p>
<pre><code class="language-cpp">typename typedef seq_car&lt;List...&gt; car;
</code></pre>
<p>Dient dazu, eben wie in Scheme zu programmieren ...</p>
<pre><code class="language-cpp">seg&lt;1,2,3&gt;::cdr;
cdr&lt;seg&lt;1,2,3&gt;&gt; // Scheme mit eckigen Klammern
</code></pre>
<p>Da ich jetzt ein <code>cons</code> habe, werde ich <code>car</code> und <code>cdr</code> (oder fuer manche <code>head</code> / <code>tail</code> ) nochmals ueberdenken. Ich bin fuer jeden Vorschlag zur Implementation von <code>head</code> / <code>car</code> offen.</p>
<p>Beispielsweise habe ich jetzt car so:</p>
<pre><code class="language-cpp">template&lt;typename&gt; struct car;

template&lt;typename Car, typename... Cdr&gt;
struct car&lt; seq&lt;Car, Cdr...&gt;&gt;
{
    typedef Car result;
};
</code></pre>
<p>Was leider bei <code>seq&lt;&gt; empty; car&lt;empty&gt;;</code> keinen Compilerfehler generiert, nun ich kann auch immerhin auf nicht auf <code>result</code> zugreifen. Das passt ins Konzept, da car&lt;empty&gt;::result bzw. eval&lt;car&lt;empty&gt;&gt; den Fehler ausloest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358941</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 08 Oct 2013 16:30:00 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 17:40:36 GMT]]></title><description><![CDATA[<p>Bei typename typedef hast du wohl einfach die beiden Keywords verdreht, sollte typedef typename heissen. Wobei du typename nicht brauchst, wenn du nicht auf einen nested-type (T::type) zugreifst. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Edit: Mit dem folgenden kannst du abfangen, dass Objekte von car&lt;empty&lt;&gt;&gt; erzeugt werden. typedefs kann man aber nicht verhindern.</p>
<p>Wenn du bereits bei Instanzierung einen Compilerfehler haben moechtest, musst du etwas tiefer in die Trickkiste greifen. Grundsaetzlich kann man mit static_assert zur Compilezeit Fehler erzeugen, allerdings wird dir der Compiler folgende Spezialisierung um die ohren Werfen, auch wenn du sie nicht verwendest:</p>
<pre><code>template &lt;&gt;
struct car&lt;seq&lt;&gt;&gt;
{
    static_assert(false, &quot;car of empty seq&quot;);
};
</code></pre>
<p>Der Compiler sieht die Spezialisierung und denkt sich &quot;Super, diesen Ausdruck kann ich direkt auswerten!&quot;. Man muss den Compiler also dazu zwingen, erst bei Instanzierung das static_assert zu pruefen.</p>
<p>Damit der Compiler den Ausdruck erst bei Instanzierung ueberprueft, muss er von Template-Parametern abhaengen. Die Idee ist also, einen Ausdruck hinzuschreiben, der zumindest einen Template-Parameter enthaelt und immer false ergibt.</p>
<p>Das laesst sich mit folgender Metafunktion erledigen:</p>
<pre><code>template &lt;typename&gt;
struct always_false
{
	static constexpr bool value = false;
};
</code></pre>
<p>Jetzt haben wir das Werkzeug, nur dummerweise befinden wir uns in einer vollstaendigen Spezialisierung, haben also keinen Template-Parameter, den man einsetzen koennte.</p>
<p>Als Workaround verpassen wir dem car-Template einen Dummy-Parameter, der einen Defaultwert bekommt. Diesen Dummy-Parameter koennen wir dann an always_false uebergeben:</p>
<pre><code>template &lt;typename, typename = void&gt;
struct car;

template &lt;typename head, typename... tail, typename dummy&gt;
struct car&lt;Seq&lt;head, tail...&gt;, dummy&gt;
{
	typedef head type;
};

template &lt;typename dummy&gt;
struct car&lt;Seq&lt;&gt;, dummy&gt;
{
	static_assert(always_false&lt;dummy&gt;::value, &quot;car of empty Seq&quot;);
};
</code></pre>
<p><a href="http://ideone.com/VC5LFv" rel="nofollow">http://ideone.com/VC5LFv</a></p>
<p>Uebrigens finde ich car als Namen sehr irrefuerhend, bin fuer head/tail. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>P.S.: Um sich bei allen Metafunktionen das typedef ersparen zu koennen, gibt es einen Shorthand:</p>
<pre><code>template &lt;typename T&gt;
struct identity
{
    typedef T type;
};
</code></pre>
<p>Dann Metafunktionen einfach von identity&lt;T&gt; ableiten:</p>
<pre><code>template &lt;typename head, typename... tail, typename dummy&gt;
struct car&lt;Seq&lt;head, tail...&gt;, dummy&gt;
    : identity&lt;head&gt;
{};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2358965</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358965</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Tue, 08 Oct 2013 17:40:36 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 18:41:34 GMT]]></title><description><![CDATA[<p>Mein Hintergrund ist, ein einfaches Scheme in C++ TMP zu programmieren. Die Basis steht. <code>car&lt;empty&lt;&gt;&gt;</code> passt dahingehend ins Konzept, dass es erstmal ein Ausdruck ist, ohne Bedeutung. Erst wenn er evaluiert wird, soll es zum Fehler kommen. Das ist der Fall.</p>
<p>Um die Herrn Abelson und Sussmann gluecklich zu machen, habe ich <code>apply</code> schnell hinzugefuegt, damit der eval-apply-Kreis geschlossen ist. Beide sind sehr trivial, da wesentliche Elemente wie &quot;Environment&quot; etc. zur Kompilezeit nicht benoetigt warden und alle Ausdruecke selbstevaluierend sind.</p>
<p>Aktuell sieht es so aus: <a href="http://ideone.com/2W0eE7" rel="nofollow">http://ideone.com/2W0eE7</a></p>
<p>Sehr vorteilhaft ist, dass Werte durch integral_constant auf Typebene geliftet werden. Spart laesstige Unterscheidungen. Naechster Schritt ist ein if_ bzw. cond zu implementieren und erste Schritte Richting filter zu wagen. Das soll in der Verallgemeinerung von fold-left gipfeln, aus denen alle weiteren Funktionen wie map, filter, concat, ... abgeleitet werden koennen. Letztendlich weiss ich nicht, ob dasausreichend ist. Es soll ja ueber Typ(transformationen) irgendwann echter Code generiert werden .... traeum ...</p>
<p>Natuerlich ist das alles recht neu fuer mich und scheitert an Kleinigkeiten. Beispielsweise:</p>
<pre><code class="language-cpp">template&lt;typename Seq&gt; using concat_fix = apply&lt;concat, s2, Seq&gt;;
</code></pre>
<p>ist innerhalb von main definiert. Der Kompiler (VS 2013) beschwert sich vermutlich zurecht:</p>
<pre><code>error C2951: template declarations are only permitted at global, namespace, or class scope
</code></pre>
<p>Gibt es ein aequivalentes typedef etc. , so dass die Definition nur lokal ist. Zur Not kann man ich sowas auch in einen anonymen Namensraum stecken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358981</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358981</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 08 Oct 2013 18:41:34 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 18:44:32 GMT]]></title><description><![CDATA[<p>In Funktionen darfst du Klassen/structs definieren, in denen wiederum typedefs stehen dürfen.</p>
<p>Das meiste TMP passiert aber sowieso auf Namespace-Ebene, ich kann mich nicht erinnern, wann ich dieses Problem mal hatte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358982</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358982</guid><dc:creator><![CDATA[mapfold]]></dc:creator><pubDate>Tue, 08 Oct 2013 18:44:32 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 18:53:01 GMT]]></title><description><![CDATA[<p>Da hat VC++ Recht.</p>
<blockquote>
<p>A <em>template-declaration</em> can appear only as a namespace scope or class scope declaration.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2358985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358985</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 08 Oct 2013 18:53:01 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Tue, 08 Oct 2013 19:07:10 GMT]]></title><description><![CDATA[<p>Hallo!<br />
Eine kleine Warnung, ich weiß nicht ob sie überhaupt zutrifft: Im Moment ist aber echt noch keine gute Zeit, um sich mit VC++ eine TMP-Bibliothek zu schreiben. Deren alias-typedef-Implementierung (&quot;using X =&quot;) ist dermaßen anfällig, dass man bestimmte Dinge so einfach nicht ausdrücken kann (interne Compiler-Crashes). Will meinen: Wenn das fehlerfrei funktioniert, dann darf man das alles wieder umschreiben.</p>
<p>Und nun wieder zum Thema: Gibt es eigentlich irgendeinen Grund, warum man etwas sequenzielles wie eine Liste als etwas behandeln sollte, dass ein Head-Element hat und dann noch irgendwas als Schwanz, das wieder ein Head-Element hat? Also gibt es einen Vorteil wenn man einer Sequenz eine &quot;Tail-Rekursion&quot; aufzwingt? Ich bin ja jetzt nicht so der funktionale Programmierer, ich ging eigentlich davon aus, dass das eher immer notgedrungen geschehen ist, weil man eben keine Variadic-Templates zur Verfügung hatte.</p>
<p>Viele Grüße</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358990</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Tue, 08 Oct 2013 19:07:10 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Wed, 09 Oct 2013 00:32:43 GMT]]></title><description><![CDATA[<p>Du brauchst keinen Zaehler/Index/Iterator. Explizite Rekursion wird nur selten benutzt, eher Rekursionsschemas. Das universellste ist fold_right (naja, eigentlich der Fixpunktoperator). Damit koennen dann viele andere Funktionen als Spezialisierung implementiert werden. Weiterhin bietet sich an, recursive Funktionen im Zusammenhang mit rekursiven Datenstrukturen zu benutzen, Baeume, Listen Arrays, ... . Desweiteren ist es einfacher Schlussfolgerungen ueber bspw. die Korrektheit des Programms abzuleiten (Induktion) oder gar Algorithmen zu berechnen. Die mathematische Basis ist viel staerker.</p>
<p>Das Gegenstueck in C++ sind explizite for-Schleifen als primitivstes Iterationsschema aehnlich expliziter Rekursion. In &lt;algorithm&gt; wird durch accumulate, transform, etc. von dieser expliziten Iteration abstrahiert und bietet vorgefertigte Iterationsschema an.</p>
<blockquote>
<p>Uebrigens finde ich car als Namen sehr irrefuerhend, bin fuer head/tail.</p>
</blockquote>
<p>Nun, cddr = cdr( cdr( ... )) oder caddr. Bei geschachtelten Listen kann es auch zu caddaddr kommen, besser zu lesen als wenn es ausgeschrieben wird oder c011011r. Aber head/tail ist auch okay, man braucht es sowieso selten.</p>
<blockquote>
<p>dann darf man das alles wieder umschreiben.</p>
</blockquote>
<p>Ich mache das nur zum Spass.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2358996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2358996</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 09 Oct 2013 00:32:43 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Wed, 23 Oct 2013 14:33:49 GMT]]></title><description><![CDATA[<p>Nachtrag: <a href="http://ideone.com/wP1GQN" rel="nofollow">http://ideone.com/wP1GQN</a></p>
<p>Interessanter Teil:</p>
<pre><code class="language-cpp">template&lt;typename B, typename C, typename A&gt; struct cond;

template&lt;typename C, typename A&gt;
struct cond&lt;std::true_type, C, A&gt;
{
    typedef C type;
};

template&lt;typename C, typename A&gt;
struct cond&lt;std::false_type, C, A&gt;
{
    typedef A type;
};

template &lt;typename S, template&lt;typename B&gt; class F&gt; struct filter_t;

//template &lt;template &lt;typename B&gt; class F, typename... Es&gt;
template &lt;typename... Es, template &lt;typename B&gt; class F&gt;
struct filter_t &lt;seq&lt;Es...&gt;, F &gt;
{
    typedef typename car&lt;seq&lt;Es...&gt;&gt;::type Car;
    typedef typename cdr&lt;seq&lt;Es...&gt;&gt;::type Cdr;
    typedef eval&lt; cond &lt; eval &lt; F &lt; Car &gt; &gt;
                       , eval &lt; cons &lt; Car, eval&lt; filter_t &lt; Cdr, F &gt; &gt; &gt; &gt;
                       , eval &lt; filter_t &lt; Cdr, F &gt; &gt;
                       &gt; &gt; type;
};

template &lt;template &lt;typename B&gt; class F&gt;
struct filter_t &lt;seq&lt;&gt;, F &gt;
{
    typedef seq&lt;&gt; type;
};

template&lt;typename A&gt; struct even;

template&lt;int I&gt;
struct even&lt;std::integral_constant&lt;int, I&gt; &gt;
{
    typedef std::integral_constant&lt;bool, I % 2 == 0&gt; type;
};
</code></pre>
<p>D.h. Filter funktioniert genauso wie es in Einstiegsliteratur fuer funktionale Programmierung beschrieben wird. Praedikate sind aehnlich einfach umzusetzen. Wie sie sich von campers Methode unterscheidet, weiss ich nicht. Habe campers Ansatz nicht verstanden, er sieht nicht ser &quot;kanonisch&quot; aus. Das staendige <code>eval</code> kann man sich sparen, mit entsprechendem <code>using</code> . Cooler ist aber ein eigener Evaluator. Andere Teile wie <code>map_t</code> funktionieren wahrscheinlich nicht, da ich mir nicht die Muehe der Korrektur gemacht habe. Vielleicht mache ich bei <code>fold_left</code> weiter, aber nicht so bald ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2362394</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2362394</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 23 Oct 2013 14:33:49 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Wed, 23 Oct 2013 18:04:24 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Nachtrag: <a href="http://ideone.com/wP1GQN" rel="nofollow">http://ideone.com/wP1GQN</a><br />
...</p>
</blockquote>
<p>Ja, so macht man das normalerweise. Genaugenommen könntest du auf die parteillen Spezialisierungen mit seq&lt;Es...&gt; auch verzichten, die notwendige Arbeit hast du durch car und cdr bereits erledigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2362484</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2362484</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 23 Oct 2013 18:04:24 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Wed, 23 Oct 2013 21:04:35 GMT]]></title><description><![CDATA[<pre><code>template&lt;typename B, typename C, typename A&gt; struct cond; 
// ...
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /></p>
<pre><code>template&lt;typename B, typename C, typename A&gt; 
using cond = std::conditional&lt; B::value, C, A &gt;;
</code></pre>
<p>?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2362525</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2362525</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 23 Oct 2013 21:04:35 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Thu, 24 Oct 2013 07:48:19 GMT]]></title><description><![CDATA[<p>Wende doch mal den identity-Trick an. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2362563</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2362563</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Thu, 24 Oct 2013 07:48:19 GMT</pubDate></item><item><title><![CDATA[Reply to Varadic Templates und funktionale Programmierung on Thu, 24 Oct 2013 08:05:43 GMT]]></title><description><![CDATA[<p>@Arcoth: Der Plan war ... ebenfalls zu entfernen und Richtung C++03 zu gehen. Auch wusste ich nicht, dass es conditional schon gibt.</p>
<p>Zu den Spezialisierungen: Ich habe einfach Schema F verfolgt. Allgemeine Definition + Spezialisierung bei allem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2362570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2362570</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Thu, 24 Oct 2013 08:05:43 GMT</pubDate></item></channel></rss>