<?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[Rekursion in Templates]]></title><description><![CDATA[<p>Aus <em>The C++ Programming Language</em> habe ich folgendes Beispiel entdeckt:</p>
<pre><code>template&lt;typename T&gt;
void g(T x)
{
    cout &lt;&lt; x &lt;&lt; &quot; &quot;;
}

template&lt;typename T, typename... Tail&gt;

void f(T head, Tail... tail)
{
    g(head); // Do something with head
    f(tail...); // try again with tail
}

void f() { } // Do nothing
</code></pre>
<p>f() ruft sich rekursiv auf bis kein Element mehr vorhanden ist. Normalerweise unterstützt ja C++ bei endrekursiven Funktionen keine Auflösung in Schleifen. Ist das bei Templates anders? D. h., muss ich keine Leistungs- und Sicherheitseinbußen haben?</p>
<p>Danke im Voraus!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/331337/rekursion-in-templates</link><generator>RSS for Node</generator><lastBuildDate>Fri, 01 May 2026 19:16:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/331337.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 23 Feb 2015 10:40:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 10:40:42 GMT]]></title><description><![CDATA[<p>Aus <em>The C++ Programming Language</em> habe ich folgendes Beispiel entdeckt:</p>
<pre><code>template&lt;typename T&gt;
void g(T x)
{
    cout &lt;&lt; x &lt;&lt; &quot; &quot;;
}

template&lt;typename T, typename... Tail&gt;

void f(T head, Tail... tail)
{
    g(head); // Do something with head
    f(tail...); // try again with tail
}

void f() { } // Do nothing
</code></pre>
<p>f() ruft sich rekursiv auf bis kein Element mehr vorhanden ist. Normalerweise unterstützt ja C++ bei endrekursiven Funktionen keine Auflösung in Schleifen. Ist das bei Templates anders? D. h., muss ich keine Leistungs- und Sicherheitseinbußen haben?</p>
<p>Danke im Voraus!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443952</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 10:40:42 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 11:30:30 GMT]]></title><description><![CDATA[<p>Du verwechselst da was.</p>
<p>Erstens liegt es im Ermessend es Compilers Tail-Rekursionen aufzulösen, was er auch machen dürfte je nach Optimierungslevel.</p>
<p>Und zweitens ist der Zeitpuntk, wo das hier geschieht ganz anders. Rekursion in Templates wird komplett zur Compiletime ausgewertet. Und dabei wird Code erzeugt.</p>
<p>Dieser kann natürlich dann wiederum zu einer Schleife optimiert werden, oder er kann weg optimiert oder sonstwie optimeirt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443965</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443965</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Mon, 23 Feb 2015 11:30:30 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 12:10:43 GMT]]></title><description><![CDATA[<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>Und zweitens ist der Zeitpuntk, wo das hier geschieht ganz anders. Rekursion in Templates wird komplett zur Compiletime ausgewertet. Und dabei wird Code erzeugt.</p>
</blockquote>
<p>Das ist klar, aber das schützt nicht per se vor rekursiven Aufrufen. Tailrekursion wird außerdem per se zur Compilezeit aufgelöst, zumindest macht es da mehr Sinn.</p>
<blockquote>
<p>Dieser kann natürlich dann wiederum zu einer Schleife optimiert werden, oder er kann weg optimiert oder sonstwie optimeirt werden.</p>
</blockquote>
<p>Wenn ich da keine Sicherheit habe, dass es so gemacht wird, weshalb sollte ich sowas programmieren? Anders ausgedrückt: Tun das die gängigen Compiler von MS, gcc, clang?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443974</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443974</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 12:10:43 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 12:19:16 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>Das ist klar, aber das schützt nicht per se vor rekursiven Aufrufen.</p>
</blockquote>
<p>Das ist technisch gesehen überhaupt keine Rekursion. Die Funktion ruft sich ja nicht selbst auf, sondern eine andere Instanz desselben Templates. Endrekursionsauflösung kommt daher nicht in Frage, aber wohl Inlining der kompletten Aufrufhierarchie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443976</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 23 Feb 2015 12:19:16 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 12:28:33 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Das ist technisch gesehen überhaupt keine Rekursion. Die Funktion ruft sich ja nicht selbst auf, sondern eine andere Instanz desselben Templates.</p>
</blockquote>
<p>Versteh ich nicht. Gibt es pro Aufruf einer Funktion in einem Template eine neue Funktions-Instanz?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443978</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 12:28:33 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 12:54:24 GMT]]></title><description><![CDATA[<p>Wenn du das template mit zb</p>
<pre><code>f(1, 2, 3);
</code></pre>
<p>aufrufst wird das doch zu (etwas wie)</p>
<pre><code>f_3(int i3) { ; }
f_2(int i2, int i3) { f_3(i3); }
f_1(int i1, int i2, int i3) { f_2(i2, i3); }
//...
f_1(1, 2, 3);
</code></pre>
<p>kompiliert. Du hast hier also gar keine Rekursion, sondern nur n (hier: 3) verschiedene funktionsaufrufe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443985</guid><dc:creator><![CDATA[f&amp;lt;&amp;gt;]]></dc:creator><pubDate>Mon, 23 Feb 2015 12:54:24 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 13:02:51 GMT]]></title><description><![CDATA[<p>@f&lt;&gt;: Mag sein, aber ich habe damit dieselben Nachteile wie bei Rekusion --&gt; Langsam und Risiko eines Stackoverflows. Es sei denn, es wird geinlined. Kann ich davon ausgehen, dass das gemacht wird?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443988</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 13:02:51 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 13:32:01 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>Aus <em>The C++ Programming Language</em> habe ich folgendes Beispiel entdeckt:</p>
<pre><code>template&lt;typename T&gt;
void g(T x)
{
    cout &lt;&lt; x &lt;&lt; &quot; &quot;;
}

template&lt;typename T, typename... Tail&gt;

void f(T head, Tail... tail)
{
    g(head); // Do something with head
    f(tail...); // try again with tail
}

void f() { } // Do nothing
</code></pre>
</blockquote>
<p>Das steht da so drin? Gleich mal schauen ob es dafür schon ein Erratum gibt...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2443990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2443990</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 23 Feb 2015 13:32:01 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 14:54:26 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>: Also ich musste, damit das kompiliert, oben einen void f(); Prototypen einbauen. Meinst du das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444001</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 14:54:26 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 15:01:46 GMT]]></title><description><![CDATA[<p>Genau. Da kein ADL stattfinden kann muss eine parameterlose Version von <code>f</code> vor der Definition des Templates deklariert sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444002</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 23 Feb 2015 15:01:46 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 15:43:03 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>@f&lt;&gt;: Mag sein, aber ich habe damit dieselben Nachteile wie bei Rekusion --&gt; Langsam und Risiko eines Stackoverflows. Es sei denn, es wird geinlined. Kann ich davon ausgehen, dass das gemacht wird?!</p>
</blockquote>
<p>Jeder gängige Kompiler macht das, wenn die Optimierungen an sind. Ansonsten wären die ganzen schönen C++11-varadic-argument-Funktionstemplates wie std::make_shared in der Tat kaum zu gebrauchen. Allerdings machen die Kompiler das nicht, wenn optimierungen ausgeschaltet sind was dazu führt das ein std::make_shared mit vielen argumenten einige Kilobyte an Stack-Speicher verbraucht, was bei uns schon öfter zu Stackoverflows bei DEBUG-Builds geführt hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444006</guid><dc:creator><![CDATA[TNA]]></dc:creator><pubDate>Mon, 23 Feb 2015 15:43:03 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 16:02:03 GMT]]></title><description><![CDATA[<p>TNA schrieb:</p>
<blockquote>
<p>Einfach schrieb:</p>
<blockquote>
<p>@f&lt;&gt;: Mag sein, aber ich habe damit dieselben Nachteile wie bei Rekusion --&gt; Langsam und Risiko eines Stackoverflows. Es sei denn, es wird geinlined. Kann ich davon ausgehen, dass das gemacht wird?!</p>
</blockquote>
<p>Jeder gängige Kompiler macht das, wenn die Optimierungen an sind.</p>
</blockquote>
<p>Bedeutet das nicht im Umkehrschluss, dass, wenn ich eine &quot;Rekursionstiefe&quot; von eine Millionen habe, dass da ganz schön großer Code erzeugt wird?! In dem Fall wäre Endrekursionsoptimierung besser.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444008</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 16:02:03 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 16:09:00 GMT]]></title><description><![CDATA[<p>Wenn du Funktionen mit einer Million Argumenten aufrufst und eine Million Templates instanziierst, hast du ganz andere Probleme als einen möglichen Stacküberlauf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444011</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444011</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 23 Feb 2015 16:09:00 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:15:27 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Wenn du Funktionen mit einer Million Argumenten aufrufst und eine Million Templates instanziierst, hast du ganz andere Probleme als einen möglichen Stacküberlauf.</p>
</blockquote>
<p>Wieso? Es kann doch sein, dass ich über eine Millionen Elemente iterieren möchte. Für einen Stackoverflow dürften 10.000 auch ausreichend sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444024</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:15:27 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:16:19 GMT]]></title><description><![CDATA[<p>Bzw. bei Inlining wird das ja nicht passieren. Dann wird der Code entsprechend groß. Auch bei 10.000 Elementen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444025</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444025</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:16:19 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:26:09 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>Bashar schrieb:</p>
<blockquote>
<p>Wenn du Funktionen mit einer Million Argumenten aufrufst und eine Million Templates instanziierst, hast du ganz andere Probleme als einen möglichen Stacküberlauf.</p>
</blockquote>
<p>Wieso? Es kann doch sein, dass ich über eine Millionen Elemente iterieren möchte. Für einen Stackoverflow dürften 10.000 auch ausreichend sein.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2444027</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444027</guid><dc:creator><![CDATA[f&amp;lt;&amp;gt;]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:26:09 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:27:28 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>Wieso? Es kann doch sein, dass ich über eine Millionen Elemente iterieren möchte. Für einen Stackoverflow dürften 10.000 auch ausreichend sein.</p>
</blockquote>
<p>Dann stellt sich eher die frage was du <em>tatsächlich</em> machen willst. Denn ich denke nicht dass du eine funktion mit 1 mio. argumenten (auch nicht mit 10000, nichtmal mit 100) aufrufen willst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444028</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444028</guid><dc:creator><![CDATA[f&amp;lt;&amp;gt;]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:27:28 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:31:07 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>@f&lt;&gt;: Mag sein, aber ich habe damit dieselben Nachteile wie bei Rekusion --&gt; Langsam und Risiko eines Stackoverflows.</p>
</blockquote>
<p>Hast du nicht btw, da die Aufrufhierachie nicht von Laufzeitvariablen abhaengt ist es trivial fuer den Compiler alles zu inlinen, oder es so zu inlinen wie er es fuer richtig haelt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444029</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:31:07 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 17:53:35 GMT]]></title><description><![CDATA[<p>f&lt;&gt; schrieb:</p>
<blockquote>
<p>Dann stellt sich eher die frage was du <em>tatsächlich</em> machen willst. Denn ich denke nicht dass du eine funktion mit 1 mio. argumenten (auch nicht mit 10000, nichtmal mit 100) aufrufen willst.</p>
</blockquote>
<p>Hm, Argumente, ok. Ich habe das mit Java verglichen. In Java sind die variablen Argumente einfach Arrays. D. h., dass ich einer Funktion mit variablen Argumenten einfach ein Array übergeben kann und es funktioniert genauso. Das scheint mit C++s variadic templates nicht zu funktionieren.<br />
Danke, für die Aufklärung! <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/2444034</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444034</guid><dc:creator><![CDATA[Einfach]]></dc:creator><pubDate>Mon, 23 Feb 2015 17:53:35 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursion in Templates on Mon, 23 Feb 2015 18:22:47 GMT]]></title><description><![CDATA[<p>Einfach schrieb:</p>
<blockquote>
<p>Hm, Argumente, ok. Ich habe das mit Java verglichen. In Java sind die variablen Argumente einfach Arrays. D. h., dass ich einer Funktion mit variablen Argumenten einfach ein Array übergeben kann und es funktioniert genauso. Das scheint mit C++s variadic templates nicht zu funktionieren.<br />
Danke, für die Aufklärung! <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>
</blockquote>
<p>Ok, mit Java kenn ich mich nicht aus, daher kann ich dazu nichts sagen. Außer dass das zwei grundlegend verschiedene mechanismn sind.</p>
<p>In C++ geht sowas ungefähr so:</p>
<pre><code>#include &lt;iostream&gt;

template &lt;typename Iterator&gt;
void display(Iterator first, Iterator last)
{
	while (first != last)
	{
		std::cout &lt;&lt; *first &lt;&lt; '\n';
		++first;
	}
}

int main()
{
	std::vector&lt;int&gt; vec = { 1, 3, 4, 6, 2, 9 }; // beliebig viele elemente
	display(vec.begin(), vec.end());
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2444044</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444044</guid><dc:creator><![CDATA[f&amp;lt;&amp;gt;]]></dc:creator><pubDate>Mon, 23 Feb 2015 18:22:47 GMT</pubDate></item></channel></rss>