<?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[[gelöst] Klassentemplate als Template-Argument]]></title><description><![CDATA[<p>Hallo,</p>
<p>aus den Tiefen der Templateprogrammierung eine Frage:</p>
<p>Ich habe ein Klassentemplate, dass verschiedene Typen von zu versendenden Daten darstellt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class DatenZumVersenden
{
    virtual void versende(Protokoll*);
};
</code></pre>
<p>und das Protokoll enthält Funktionen, um verschiedene dieser Daten zu versenden:</p>
<pre><code class="language-cpp">class Protkoll {
    virtual void verschicke(DatenZumVersenden&lt;int&gt;&amp; daten);
    virtual void verschicke(DatenZumVersenden&lt;float&gt;&amp; daten);
//usw...
};
</code></pre>
<p>Jetzt gibt es aber verschiedene Ausprägungen von zu versendenen Daten, die unterschiedliche &quot;Metadaten&quot; mit sich herumschleppen. Da diese Metadaten sehr unterschiedlich sind, macht es keinen Sinn, Protokolle von Protokoll erben zu lassen, da ich sonst dynamic_cast machen müsste, um von DatenZumVersenden&lt;T&gt; auf SpezielleDatenZumVersenden&lt;T&gt; zu kommen.</p>
<p>Daher habe ich eine Art &quot;Mixin&quot; konstruiert:</p>
<pre><code class="language-cpp">template&lt;template &lt;class U&gt; class T&gt;
class ProtokollAdapter
{
    virtual void versende(T&lt;int&gt;&amp; daten);
    virtual void versende(T&lt;float&gt;&amp; daten);
};
</code></pre>
<p>und die dazugehörigen Daten:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class DatenZumVersenden
{
    virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
};
</code></pre>
<p>Jetzt ist das erstellen eines neue Protokolls dann sehr einfach und vorallem ohne dynamic_casts möglich:</p>
<pre><code class="language-cpp">class SpeziellesProtokoll: public ProtokollApater&lt;SpezielleDaten&gt;{
    virtual void versende(SpezielleDaten&lt;int&gt;&amp; daten);
};
</code></pre>
<p>Doch grau ist alle Theorie.</p>
<p>Das Problem ist, dass der Compiler es nicht bei Klassentemplates belässt und implizit das template Argument &quot;hinschreibt&quot;.</p>
<p>Der genaue Fehler ist:</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
</code></pre>
<pre><code>error: template argument 1 is invalid
error: type/value mismatch at argument 1 in template parameter list for ‘template&lt;template&lt;class U&gt; class T&gt; class ProtokollAdapter’
error:   expected a class template, got ‘DatenZumVersenden&lt;T&gt;’
</code></pre>
<p>Also</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
</code></pre>
<p>wird für den Kompiler implizit zu</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&lt;T&gt; &gt;*);
</code></pre>
<p>Wo liegt mein Denkfehler?</p>
<p>Gruß,<br />
Phil</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243300/gelöst-klassentemplate-als-template-argument</link><generator>RSS for Node</generator><lastBuildDate>Sun, 20 Sep 2026 03:54:50 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243300.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Jun 2009 11:22:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [gelöst] Klassentemplate als Template-Argument on Mon, 15 Jun 2009 11:35:58 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>aus den Tiefen der Templateprogrammierung eine Frage:</p>
<p>Ich habe ein Klassentemplate, dass verschiedene Typen von zu versendenden Daten darstellt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class DatenZumVersenden
{
    virtual void versende(Protokoll*);
};
</code></pre>
<p>und das Protokoll enthält Funktionen, um verschiedene dieser Daten zu versenden:</p>
<pre><code class="language-cpp">class Protkoll {
    virtual void verschicke(DatenZumVersenden&lt;int&gt;&amp; daten);
    virtual void verschicke(DatenZumVersenden&lt;float&gt;&amp; daten);
//usw...
};
</code></pre>
<p>Jetzt gibt es aber verschiedene Ausprägungen von zu versendenen Daten, die unterschiedliche &quot;Metadaten&quot; mit sich herumschleppen. Da diese Metadaten sehr unterschiedlich sind, macht es keinen Sinn, Protokolle von Protokoll erben zu lassen, da ich sonst dynamic_cast machen müsste, um von DatenZumVersenden&lt;T&gt; auf SpezielleDatenZumVersenden&lt;T&gt; zu kommen.</p>
<p>Daher habe ich eine Art &quot;Mixin&quot; konstruiert:</p>
<pre><code class="language-cpp">template&lt;template &lt;class U&gt; class T&gt;
class ProtokollAdapter
{
    virtual void versende(T&lt;int&gt;&amp; daten);
    virtual void versende(T&lt;float&gt;&amp; daten);
};
</code></pre>
<p>und die dazugehörigen Daten:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class DatenZumVersenden
{
    virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
};
</code></pre>
<p>Jetzt ist das erstellen eines neue Protokolls dann sehr einfach und vorallem ohne dynamic_casts möglich:</p>
<pre><code class="language-cpp">class SpeziellesProtokoll: public ProtokollApater&lt;SpezielleDaten&gt;{
    virtual void versende(SpezielleDaten&lt;int&gt;&amp; daten);
};
</code></pre>
<p>Doch grau ist alle Theorie.</p>
<p>Das Problem ist, dass der Compiler es nicht bei Klassentemplates belässt und implizit das template Argument &quot;hinschreibt&quot;.</p>
<p>Der genaue Fehler ist:</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
</code></pre>
<pre><code>error: template argument 1 is invalid
error: type/value mismatch at argument 1 in template parameter list for ‘template&lt;template&lt;class U&gt; class T&gt; class ProtokollAdapter’
error:   expected a class template, got ‘DatenZumVersenden&lt;T&gt;’
</code></pre>
<p>Also</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
</code></pre>
<p>wird für den Kompiler implizit zu</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&lt;T&gt; &gt;*);
</code></pre>
<p>Wo liegt mein Denkfehler?</p>
<p>Gruß,<br />
Phil</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1726878</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1726878</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Mon, 15 Jun 2009 11:35:58 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst] Klassentemplate als Template-Argument on Mon, 15 Jun 2009 11:37:11 GMT]]></title><description><![CDATA[<p>Na dann geb ich mir mal selbst die Antwort (google ist mein Freund).</p>
<p>Ersetze</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt;DatenZumVersenden&gt;*);
</code></pre>
<p>durch</p>
<pre><code class="language-cpp">virtual void versende(Protokoll&lt; ::DatenZumVersenden&gt;*);
</code></pre>
<p>Man beachte das Leerzeichen zwischen &lt; und ::</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1726890</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1726890</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Mon, 15 Jun 2009 11:37:11 GMT</pubDate></item></channel></rss>