<?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[Template Metaprogramming &amp;amp; branching]]></title><description><![CDATA[<p>Folgendes Problem:</p>
<p>Ich will in einer Klasse abhängig von irgendwelchen Eigenschaften den Programmfluss ändern (eben branching). Dabei soll aber nur der Zweig instanziert werden, der nachher auch ausgeführt wird. Bsp:</p>
<pre><code class="language-cpp">template&lt; class WrapperParam &gt;
class XY
{
public:
    template&lt; class FunctionParam &gt;
    void function()
    {
        if( is_complete_type&lt; FunctionParam &gt;::value )
        {
            FunctionParam object2; //dazu muss FunctionParam eine Definition haben
        }
        else
        {
        }
    }
};
</code></pre>
<p>Das wird ja so nicht funktionieren wie es eigentlich geplant war, da auch wenn FunctionParam nur eine Deklaration ist &quot;FunctionParam object;&quot; instanziert wird. Man muss also die beiden Zweige wieder in template Funktionen auslagern, und dann abhängig von irgendeinem konstanten bool instanzieren und aufrufen. In der Praxis müsste ich in diesen Funktionen auch auf &quot;WrapperParam&quot; und die member meiner Klasse zugreifen.<br />
Wie löst man sowas am geschicktesten (d.h. möglichst wenig boilerplate)?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/291093/template-metaprogramming-amp-branching</link><generator>RSS for Node</generator><lastBuildDate>Mon, 17 Aug 2026 22:23:13 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/291093.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 10 Aug 2011 13:51:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 13:51:18 GMT]]></title><description><![CDATA[<p>Folgendes Problem:</p>
<p>Ich will in einer Klasse abhängig von irgendwelchen Eigenschaften den Programmfluss ändern (eben branching). Dabei soll aber nur der Zweig instanziert werden, der nachher auch ausgeführt wird. Bsp:</p>
<pre><code class="language-cpp">template&lt; class WrapperParam &gt;
class XY
{
public:
    template&lt; class FunctionParam &gt;
    void function()
    {
        if( is_complete_type&lt; FunctionParam &gt;::value )
        {
            FunctionParam object2; //dazu muss FunctionParam eine Definition haben
        }
        else
        {
        }
    }
};
</code></pre>
<p>Das wird ja so nicht funktionieren wie es eigentlich geplant war, da auch wenn FunctionParam nur eine Deklaration ist &quot;FunctionParam object;&quot; instanziert wird. Man muss also die beiden Zweige wieder in template Funktionen auslagern, und dann abhängig von irgendeinem konstanten bool instanzieren und aufrufen. In der Praxis müsste ich in diesen Funktionen auch auf &quot;WrapperParam&quot; und die member meiner Klasse zugreifen.<br />
Wie löst man sowas am geschicktesten (d.h. möglichst wenig boilerplate)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104458</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104458</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 10 Aug 2011 13:51:18 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 13:56:54 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template &lt;bool B&gt;
struct bool_to_type
{
    static const int value = B;
};

template &lt;typename T&gt;
class XY
{
    template &lt;typename U&gt;
    void function(bool_to_type&lt;true&gt;)
    {
        // ...
    }

    template &lt;typename U&gt;
    void function(bool_to_type&lt;false&gt;)
    {
        // ...
    }

public:

    template &lt;typename U&gt;
    void function()
    {
        function&lt;U&gt;(bool_to_type&lt;is_complete_type&lt;T&gt;::value&gt;());
    }
};
</code></pre>
<p>So vielleicht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104462</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Wed, 10 Aug 2011 13:56:54 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 14:08:20 GMT]]></title><description><![CDATA[<p>Nicht vielleicht, das ist ziemlich genau was ich gesucht habe, danke <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="🙂"
    /><br />
Das einzige, was mich stört ist, dass man da einen Parameter übergeben muss... meinst du gängige compiler (vor allem gcc) erkennen, dass ich den Parameter nicht brauche und optimieren ihn weg? (ich geh jetzt mal ungetestet davon aus, dass die Hilfsfunktion eh inline ist)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104466</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104466</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 10 Aug 2011 14:08:20 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 14:09:26 GMT]]></title><description><![CDATA[<p>Der Parameter hat keinen Namen, außerdem hat bool_to_type keine Member. Ich bin mir zu 100% sicher, dass das von jedem Compiler wegoptimiert wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104467</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104467</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Wed, 10 Aug 2011 14:09:26 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 14:25:53 GMT]]></title><description><![CDATA[<p>ergibt Sinn, danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104474</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104474</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 10 Aug 2011 14:25:53 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 18:06:01 GMT]]></title><description><![CDATA[<p>Kann man das nicht auch als</p>
<pre><code class="language-cpp">template&lt; class WrapperParam &gt;
class XY
{
private:
    template&lt;bool b, typename FunctionParam&gt;
    class Helper
    {
        static void HelperFunc()
        {
            FunctionParam object2;
        }
    }
    template&lt;typename FunctionParam&gt;
    class Helper&lt;false, FunctionParam&gt;
    {
        static void HelperFunc()
        {
        }
    }
public:
    template&lt; class FunctionParam &gt;
    void function()
    {
        Helper&lt;is_complete_type&lt; FunctionParam &gt;::value&gt;::HelperFunc();
    }
};
</code></pre>
<p>regeln? So mit ohne Parameterübergabe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104592</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104592</guid><dc:creator><![CDATA[Cachus]]></dc:creator><pubDate>Wed, 10 Aug 2011 18:06:01 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 18:09:50 GMT]]></title><description><![CDATA[<p>Das welchen Vorteil hätte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104594</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104594</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Wed, 10 Aug 2011 18:09:50 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 18:22:30 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Das welchen Vorteil hätte?</p>
</blockquote>
<p>Den Parameter sparen, der wohl doch nur wegoptimiert werden kann, wenn die Funktion inline ist oder der Compiler link time code generation macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104602</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104602</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 10 Aug 2011 18:22:30 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 18:57:08 GMT]]></title><description><![CDATA[<p>Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104619</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104619</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 10 Aug 2011 18:57:08 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 19:31:57 GMT]]></title><description><![CDATA[<p>Cachus schrieb:</p>
<blockquote>
<p>Kann man das nicht auch als</p>
<pre><code class="language-cpp">template&lt; class WrapperParam &gt;
class XY
{
private:
    template&lt;bool b, typename FunctionParam&gt;
    class Helper
    {
        static void HelperFunc()
        {
            FunctionParam object2;
        }
    }
    template&lt;typename FunctionParam&gt;
    class Helper&lt;false, FunctionParam&gt;
    {
        static void HelperFunc()
        {
        }
    }
public:
    template&lt; class FunctionParam &gt;
    void function()
    {
        Helper&lt;is_complete_type&lt; FunctionParam &gt;::value&gt;::HelperFunc();
    }
};
</code></pre>
<p>regeln? So mit ohne Parameterübergabe</p>
</blockquote>
<p>So hab ich das bis jetzt auch gemacht, aber das ganze ist ziemlich umständlich:<br />
- Klasse definieren<br />
- Zugriff auf member der Klasse ist kompliziert, man muss this pointer mit übergeben etc... ich finde 314s Lösung besser.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104634</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104634</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 10 Aug 2011 19:31:57 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 20:45:39 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.</p>
</blockquote>
<p>Weswegen das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104648</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104648</guid><dc:creator><![CDATA[Nachgefragt...]]></dc:creator><pubDate>Wed, 10 Aug 2011 20:45:39 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Wed, 10 Aug 2011 23:54:09 GMT]]></title><description><![CDATA[<p>Nachgefragt... schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.</p>
</blockquote>
<p>Weswegen das?</p>
</blockquote>
<p>ISO 14882.2003 schrieb:</p>
<blockquote>
<p>3.2 One definition rule [basic.def.odr]<br />
...<br />
5 <strong>There can be more than one definition of a</strong> class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), <strong>member function of a class template</strong> (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.4) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then<br />
— each definition of D shall consist of the same sequence of tokens; and<br />
— <strong>in each definition of D, corresponding names</strong>, looked up according to 3.4, shall refer to an entity defined within the definition of D, or <strong>shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3)</strong>, except that a name can refer to a const object with internal or no linkage if the object has the same integral or enumeration type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D; and<br />
— in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and<br />
— in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if its token sequence were present in the definition of D; that is, the default argument is subject to the three requirements described above (and, if the default argument has sub-expressions with default arguments, this requirement applies recursively).25)<br />
— if D is a class with an implicitly-declared constructor (12.1), it is as if the constructor was implicitly defined in every translation unit where it is used, and the implicit definition in every translation unit shall call the same constructor for a base class or a class member of D. [Example:<br />
...—end example] <strong>If D is a template, and is defined in more than one translation unit, then the last four requirements from the list above shall apply</strong> to names from the template’s enclosing scope used in the template definition (14.6.3), and <strong>also to dependent names at the point of instantiation (14.6.2)</strong>. If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.</p>
</blockquote>
<p>Im Allgemeinen ist davon auszugehen, dass die betreffende Klasse irgendwo mal vollständig definiert wird. Sollte in der jeweiligen ÜE dann ein entsprechender Aufruf stehen, gibt es ein Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104692</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 10 Aug 2011 23:54:09 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Thu, 11 Aug 2011 04:04:56 GMT]]></title><description><![CDATA[<p>ich sehe da jetzt kein Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104699</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Thu, 11 Aug 2011 04:04:56 GMT</pubDate></item><item><title><![CDATA[Reply to Template Metaprogramming &amp;amp; branching on Thu, 11 Aug 2011 11:57:52 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>ich sehe da jetzt kein Problem.</p>
</blockquote>
<p>z.B. in Pis Version</p>
<pre><code class="language-cpp">template &lt;typename U&gt;
    void function()
    {
        function&lt;U&gt;(bool_to_type&lt;is_complete_type&lt;T&gt;::value&gt;());
    }
</code></pre>
<p>Je nach Typ und Punkt der Instantiierung ist das entweder:</p>
<pre><code class="language-cpp">function&lt;U&gt;(bool_to_type&lt;true&gt;())
</code></pre>
<p>oder</p>
<pre><code class="language-cpp">function&lt;U&gt;(bool_to_type&lt;false&gt;())
</code></pre>
<p>also völlig verschiedene Dinge. Die Abhängigkeit vom Instantiierungsort ist hier das Problem: Die ODR sagt klar, dass die Bedeutung an allen Instantiierungsorten gleich sein muss. Ist der Typ nun an einigen Instantiierungsstellen unvollständig, and anderen aber vollständig, so ist die ODR offenbar verletzt.<br />
Grundsätzlich ist es gefährlich is_complete auf diese Weise einzusetzen. Meiner Ansicht nach ist das primär für compile-time assertions nützlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2104847</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2104847</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Aug 2011 11:57:52 GMT</pubDate></item></channel></rss>