<?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[Templates: Partielle Spezialisierung oder Vererbung]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe schreibe gerade an einer generischen Vektorklasse für eine Mathebibliothek. Dabei soll es eine Template Klasse geben, die über einen Typen und die Anzahl der Komponenten im Vektor parametrisiert werden kann.</p>
<p>Zum Beispiel so:</p>
<pre><code class="language-cpp">Vector&lt;float, 3&gt; v1;
Vector&lt;int, 8&gt; v2;
</code></pre>
<p>Dies sieht bei mir so aus: (Ich habe die Klasse auf die für das Problem relevanten Teile reduziert.)</p>
<pre><code class="language-cpp">template &lt;typename T, int size&gt;
class Vector
{
  public:
    Vector();
    Vector&lt;T, size&gt;&amp; operator = (const Vector&lt;T, size&gt;&amp; src);
    Vector&lt;T, size&gt; operator + (const Vector&lt;T, size&gt;&amp; src) const;

  protected:
    T vec[size];      //!&lt; Speicher für die Werte
};
</code></pre>
<p>Jetzt möchte ich für bestimmte Vektoren (2- und 3-dinemsionale) zusätzliche Konstruktoren und Methoden hinzufügen.</p>
<p>Dafür habe ich zunächst folgenden naiven Ansatz gewählt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class Vector2D : public Vector&lt;T, 2&gt; // Korrektur
{
  public:
    Vector2D();
    Vector2D(T x, T y);
    Vector2D&lt;T&gt;&amp; operator = (const Vector&lt;T, 2&gt;&amp; src);
};
</code></pre>
<p>Folgender Ausdruck führt so aber zu einem Fehler:</p>
<pre><code class="language-cpp">Vector2D&lt;float&gt; v1, v2, v3;
v3 = v1 + v2;
</code></pre>
<p>Der Fehler ist hierbei, dass v1 + v2 zu einem Vector&lt;float, 2&gt; ausgewertet wird und v3 aber ein Vector2D&lt;float&gt; ist, was einen impliziten Downcast zu folge hätte.</p>
<p>Warum greift an dieser stelle nicht mein Vector2D::operator=?</p>
<p>Eine Möglichkeit das o.g. problem zu lösen, wäre natürlich die Operatoren (hier nur +) aus Vector nochmal in Vector3D zu implementieren, was ich, aufgrund der Codeverdopplung, als unschön ansehe.</p>
<p>Eine andere Möglichkeit, von der ich gelesen habe ist, die partielle Spezialisierung von Template Klassen. Dies habe ich mal folgendermaßen probiert:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector&lt;T, 2&gt;
{
  public:
    Vector(T x, T y);
};
</code></pre>
<p>Leider erfüllt dieser Code so auch nicht seinen Zweck, da Vector&lt;T, 2&gt; die Ursprungsklasse für den Fall size=2 komplett ersetzt und nicht nur ergänzt.</p>
<p>Nun zur meiner Abschließenden frage:</p>
<p>Was ist der beste weg eine generische Klasse zu benutzen um speziellere Unterklassen zu erzeugen, bei denen nicht alle operatoren neu implementiert werden müssen?</p>
<p>Vielen Dank für die Hilfe.</p>
<p>kie</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/263032/templates-partielle-spezialisierung-oder-vererbung</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 05:55:12 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/263032.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Mar 2010 08:47:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:51:53 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe schreibe gerade an einer generischen Vektorklasse für eine Mathebibliothek. Dabei soll es eine Template Klasse geben, die über einen Typen und die Anzahl der Komponenten im Vektor parametrisiert werden kann.</p>
<p>Zum Beispiel so:</p>
<pre><code class="language-cpp">Vector&lt;float, 3&gt; v1;
Vector&lt;int, 8&gt; v2;
</code></pre>
<p>Dies sieht bei mir so aus: (Ich habe die Klasse auf die für das Problem relevanten Teile reduziert.)</p>
<pre><code class="language-cpp">template &lt;typename T, int size&gt;
class Vector
{
  public:
    Vector();
    Vector&lt;T, size&gt;&amp; operator = (const Vector&lt;T, size&gt;&amp; src);
    Vector&lt;T, size&gt; operator + (const Vector&lt;T, size&gt;&amp; src) const;

  protected:
    T vec[size];      //!&lt; Speicher für die Werte
};
</code></pre>
<p>Jetzt möchte ich für bestimmte Vektoren (2- und 3-dinemsionale) zusätzliche Konstruktoren und Methoden hinzufügen.</p>
<p>Dafür habe ich zunächst folgenden naiven Ansatz gewählt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class Vector2D : public Vector&lt;T, 2&gt; // Korrektur
{
  public:
    Vector2D();
    Vector2D(T x, T y);
    Vector2D&lt;T&gt;&amp; operator = (const Vector&lt;T, 2&gt;&amp; src);
};
</code></pre>
<p>Folgender Ausdruck führt so aber zu einem Fehler:</p>
<pre><code class="language-cpp">Vector2D&lt;float&gt; v1, v2, v3;
v3 = v1 + v2;
</code></pre>
<p>Der Fehler ist hierbei, dass v1 + v2 zu einem Vector&lt;float, 2&gt; ausgewertet wird und v3 aber ein Vector2D&lt;float&gt; ist, was einen impliziten Downcast zu folge hätte.</p>
<p>Warum greift an dieser stelle nicht mein Vector2D::operator=?</p>
<p>Eine Möglichkeit das o.g. problem zu lösen, wäre natürlich die Operatoren (hier nur +) aus Vector nochmal in Vector3D zu implementieren, was ich, aufgrund der Codeverdopplung, als unschön ansehe.</p>
<p>Eine andere Möglichkeit, von der ich gelesen habe ist, die partielle Spezialisierung von Template Klassen. Dies habe ich mal folgendermaßen probiert:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector&lt;T, 2&gt;
{
  public:
    Vector(T x, T y);
};
</code></pre>
<p>Leider erfüllt dieser Code so auch nicht seinen Zweck, da Vector&lt;T, 2&gt; die Ursprungsklasse für den Fall size=2 komplett ersetzt und nicht nur ergänzt.</p>
<p>Nun zur meiner Abschließenden frage:</p>
<p>Was ist der beste weg eine generische Klasse zu benutzen um speziellere Unterklassen zu erzeugen, bei denen nicht alle operatoren neu implementiert werden müssen?</p>
<p>Vielen Dank für die Hilfe.</p>
<p>kie</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869116</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869116</guid><dc:creator><![CDATA[kie]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:51:53 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:04:08 GMT]]></title><description><![CDATA[<p>kie schrieb:</p>
<blockquote>
<p>Der Fehler ist hierbei, dass v1 + v2 zu einem Vector&lt;float, 2&gt; ausgewertet wird und v3 aber ein Vector2D&lt;float&gt; ist, was einen impliziten Downcast zu folge hätte.</p>
<p>Warum greift an dieser stelle nicht mein Vector2D::operator=?</p>
</blockquote>
<p>Weil du nach dem <code>operator+</code> ein <code>Vector&lt;float, 2&gt;</code> hast und nicht ein <code>Vector2D</code> .</p>
<p>kie schrieb:</p>
<blockquote>
<p>Was ist der beste weg eine generische Klasse zu benutzen um speziellere Unterklassen zu erzeugen, bei denen nicht alle operatoren neu implementiert werden müssen?</p>
</blockquote>
<p>kie schrieb:</p>
<blockquote>
<p>Jetzt möchte ich für bestimmte Vektoren (2- und 3-dinemsionale) zusätzliche Konstruktoren und Methoden hinzufügen.</p>
</blockquote>
<p>Spezifiziere dies bitte genauer, dann kann man auch besser helfen.</p>
<p>Es gäbe zum Beispiel die Möglichkeit von freien Funktionen. Oder man kann über Zwischentypen gehen. Allerdings frage ich mich sowieso, wieso ein <code>Vector2D</code> plötzlich eine andere Schnittstelle haben sollte wie ein <code>Vector3D</code> . Sowas verwirrt eher, als dass es hilfreich ist.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869119</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869119</guid><dc:creator><![CDATA[Dravere_logoff]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:04:08 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:47:39 GMT]]></title><description><![CDATA[<p>Dravere_logoff schrieb:</p>
<blockquote>
<p>Weil du nach dem <code>operator+</code> ein <code>Vector&lt;float, 2&gt;</code> hast und nicht ein <code>Vector2D</code> .</p>
</blockquote>
<p>Aber mein <code>operator=</code> ist mit einem <code>Vector&lt;float,2&gt;</code> als r-value definiert, ändert das nichts?</p>
<p>Dravere_logoff schrieb:</p>
<blockquote>
<p>Spezifiziere dies bitte genauer, dann kann man auch besser helfen.</p>
<p>Es gäbe zum Beispiel die Möglichkeit von freien Funktionen. Oder man kann über Zwischentypen gehen. Allerdings frage ich mich sowieso, wieso ein <code>Vector2D</code> plötzlich eine andere Schnittstelle haben sollte wie ein <code>Vector3D</code> . Sowas verwirrt eher, als dass es hilfreich ist.</p>
</blockquote>
<p>1. Vector2D und Vector3D werden in meinem Programm sehr oft benutzt und sollen deshalb komponentenweise Konstruktoren haben.</p>
<p>2. Ein Vector3D soll auch das Kreuzprodukt implementieren, welches nur für 3-dimensionale Vektoren definiert ist.</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869123</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869123</guid><dc:creator><![CDATA[kie]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:47:39 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:40:03 GMT]]></title><description><![CDATA[<p>kie schrieb:</p>
<blockquote>
<p>Aber mein <code>operator=</code> ist mit einem <code>Vector&lt;float,2&gt;</code> als r-value definiert, ändert das nichts?</p>
</blockquote>
<p>Ist schwer zu sagen, weil du so viele Schreibfehler in deinem Code hast. Du schreibst zum Teil von 3D, dann ist es wieder 2D, der <code>operator=</code> erwartet zum Beispiel ein <code>Vector&lt;float, size&gt;</code> und nicht ein <code>Vector&lt;float, 2&gt;</code> , ich bin einfach davon ausgegangen, dass du einen normalen <code>operator=</code> implementiert hast <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>Zum Rest komme ich später noch oder jemand anderes, gerade keine Zeit mehr <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>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869135</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869135</guid><dc:creator><![CDATA[Dravere_logoff]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:40:03 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:46:13 GMT]]></title><description><![CDATA[<p>Dravere_logoff schrieb:</p>
<blockquote>
<p>Ist schwer zu sagen, weil du so viele Schreibfehler in deinem Code hast. Du schreibst zum Teil von 3D, dann ist es wieder 2D...</p>
</blockquote>
<p>Hab einen Fehler korrigiert.</p>
<p>Der Code bezieht sich nur auf Vector2D, da die Idee für Vector3D analog ist. Jedoch möchte ich beides implementieren, weshalb ich im Text von beidem spreche.<br />
Ich hoffe, nun sind gewisse Verwirrungen beseitigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869136</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869136</guid><dc:creator><![CDATA[kie]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:46:13 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:53:30 GMT]]></title><description><![CDATA[<p>kie schrieb:</p>
<blockquote>
<p>Hab einen Fehler korrigiert.</p>
</blockquote>
<p>Den anderen dafür nicht. In vector2D ist size nicht bekannt, was soll also der <code>Vector2D&lt;T&gt;&amp; operator = (const Vector&lt;T, size&gt;&amp; src);</code> wirklich sein?</p>
<p>Ich würd vermutlich eine Erzeugendenfunktion machen und die Ableitung weglassen, wenns wirklich nur um die Konstruktion geht:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
Vector&lt;T, 2&gt; makeVector2D(T const&amp; t1, T const&amp; t2)
{
  Vector&lt;T, 2&gt; tmp;
  /* Werte belegen */
  return tmp;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1869138</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869138</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:53:30 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:54:23 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>kie schrieb:</p>
<blockquote>
<p>Hab einen Fehler korrigiert.</p>
</blockquote>
<p><strong>Einen</strong> anderen dafür nicht. In vector2D ist size nicht bekannt, was soll also der <code>Vector2D&lt;T&gt;&amp; operator = (const Vector&lt;T, size&gt;&amp; src);</code> wirklich sein?</p>
</blockquote>
<p>Danke für den Hinweis. Habs korrigiert. Size muss da durch eine 2 ersetzt werden, damit es mathematisch Sinn macht!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869139</guid><dc:creator><![CDATA[kie]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:54:23 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 09:56:10 GMT]]></title><description><![CDATA[<p>kie schrieb:</p>
<blockquote>
<p>pumuckl schrieb:</p>
<blockquote>
<p>kie schrieb:</p>
<blockquote>
<p>Hab einen Fehler korrigiert.</p>
</blockquote>
<p><strong>Einen</strong> anderen dafür nicht. In vector2D ist size nicht bekannt, was soll also der <code>Vector2D&lt;T&gt;&amp; operator = (const Vector&lt;T, size&gt;&amp; src);</code> wirklich sein?</p>
</blockquote>
<p>Danke für den Hinweis. Habs korrigiert. Size muss da durch eine 2 ersetzt werden, damit es mathematisch Sinn macht!</p>
</blockquote>
<p>Danke für die Antwort:<br />
Es geht nicht nur um die Konstruktion, sondern auch darum, dass ein Vector3D das Kreuzprodukt hat und der Vector2D nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869140</guid><dc:creator><![CDATA[kie]]></dc:creator><pubDate>Mon, 15 Mar 2010 09:56:10 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 10:01:57 GMT]]></title><description><![CDATA[<p>kie schrieb:</p>
<blockquote>
<p>Es geht nicht nur um die Konstruktion, sondern auch darum, dass ein Vector3D das Kreuzprodukt hat und der Vector2D nicht.</p>
</blockquote>
<p>Wenn ich mal davon ausgehen kann dass du entsprechende Getter für die einzelnen Elemente hast, ist das Kreuzprodukt sowieso eine freie Funktion. Immernoch kein Grund für eine eigene Klasse also <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/1869143</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869143</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 15 Mar 2010 10:01:57 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 11:04:46 GMT]]></title><description><![CDATA[<p>Ich habe auch so ein Klassen-Template (&quot;point&quot;) in meiner Sammlung. Die Initialisierung könnte man mit &quot;SFINAE&quot; lösen, aber das ist wirklich Overkill. Stattdessen habe ich mir make_point-Funktionen gebaut:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
inline point&lt;T,2&gt; make_point(T const&amp; x, T const&amp; y) { [...] }

template&lt;typename T&gt;
inline point&lt;T,3&gt; make_point(T const&amp; x, T const&amp; y, T const&amp; z) { [...] }

template&lt;typename T&gt;
inline point&lt;T,4&gt; make_point(T const&amp; x, T const&amp; y, T const&amp; z, T const&amp; w) { [...] }
</code></pre>
<p>Das ist genauso effizient im Vergleich zu einem Kontruktor (bei einem guten Compiler) und kann dir die Benennung des Typs ersparen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869173</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869173</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Mon, 15 Mar 2010 11:04:46 GMT</pubDate></item><item><title><![CDATA[Reply to Templates: Partielle Spezialisierung oder Vererbung on Mon, 15 Mar 2010 11:27:26 GMT]]></title><description><![CDATA[<p>Es gäbe im übrigen noch die Möglichkeit das Klassentemplate als POD zu implementieren. Dann kann man folgendes schreiben:</p>
<pre><code class="language-cpp">typedef Vector&lt;float, 3&gt; Vec3f;
Vec3f vec = { 1.f, 2.f, 3.f };
</code></pre>
<p>Kreuzprodukt würde ich auch über eine freie Funktion implementieren.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869185</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 11:27:26 GMT</pubDate></item></channel></rss>