<?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[Templatespezialisierung und abgeleitete Klassen]]></title><description><![CDATA[<p>Hallo,</p>
<p>wenn ich folgendes mache:</p>
<pre><code class="language-cpp">class A{};

class B: public A {};

template&lt;typename T&gt; void foo(T t)
{
  cout&lt;&lt;&quot;Unspezialisiert&quot;&lt;&lt;endl;
}

template&lt;&gt; void foo(A a){
  cout&lt;&lt;&quot;Auf A spezialisiert&quot;&lt;&lt;endl;
}

int main()
{
  B b;
  foo(b);
}
</code></pre>
<p>Dann wird die unspezialisierte Version von foo aufgerufen. Ich hätte gerne, dass automatisch die spezialisierteste Version des Templates verwendet wird, schließlich ist B ein A. Gibt es da irgendeine Programmierstruktur die dies leisten kann? Den Fall von Mehrfachvererbung kann ich ausschließen, wäre natürlich schick, wenn es für den Fall auch ginge.</p>
<p>Ich meine dabei jetzt nicht, foo&lt;A&gt;(b) zu benutzen. Im Beispiel geht das noch, aber bei komplizierteren Strukturen müsste ich dann immer Nachgucken, für welche der Basisklassen foo das spezialisierteste Template besitzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/246209/templatespezialisierung-und-abgeleitete-klassen</link><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 03:31:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/246209.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 24 Jul 2009 13:30:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Fri, 24 Jul 2009 13:30:58 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>wenn ich folgendes mache:</p>
<pre><code class="language-cpp">class A{};

class B: public A {};

template&lt;typename T&gt; void foo(T t)
{
  cout&lt;&lt;&quot;Unspezialisiert&quot;&lt;&lt;endl;
}

template&lt;&gt; void foo(A a){
  cout&lt;&lt;&quot;Auf A spezialisiert&quot;&lt;&lt;endl;
}

int main()
{
  B b;
  foo(b);
}
</code></pre>
<p>Dann wird die unspezialisierte Version von foo aufgerufen. Ich hätte gerne, dass automatisch die spezialisierteste Version des Templates verwendet wird, schließlich ist B ein A. Gibt es da irgendeine Programmierstruktur die dies leisten kann? Den Fall von Mehrfachvererbung kann ich ausschließen, wäre natürlich schick, wenn es für den Fall auch ginge.</p>
<p>Ich meine dabei jetzt nicht, foo&lt;A&gt;(b) zu benutzen. Im Beispiel geht das noch, aber bei komplizierteren Strukturen müsste ich dann immer Nachgucken, für welche der Basisklassen foo das spezialisierteste Template besitzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1748904</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1748904</guid><dc:creator><![CDATA[Templateanfänger]]></dc:creator><pubDate>Fri, 24 Jul 2009 13:30:58 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Fri, 24 Jul 2009 13:53:57 GMT]]></title><description><![CDATA[<p>Es ist zwar nicht genau das, was du suchst, aber man kann mit Operatorüberladung und einer gemeinsamen Basisklasse etwas ähnliches machen:</p>
<pre><code class="language-cpp">class Base{};

class A: public Base {};

class B: public A{};

class C: public Base{};

void foo(A a){
  cout&lt;&lt;&quot;Auf A spezialisiert&quot;&lt;&lt;endl;
}

void foo(Base t)
{
  cout&lt;&lt;&quot;Unspezialisiert&quot;&lt;&lt;endl;
}

int main()
{
  A a;
  B b;
  C c;
  foo(a);  // Spezialisiert auf A
  foo(b);  // Spezialisiert auf A
  foo(c);  // Unspezialisiert
}
</code></pre>
<p>Das ist dann natürlich weniger universell als templates <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1748918</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1748918</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 24 Jul 2009 13:53:57 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Fri, 24 Jul 2009 14:19:18 GMT]]></title><description><![CDATA[<p>Da würde Liskov gar nicht gefallen. Du versuchst hier mit Compiletime-Polymorphie unterschiedlich auf Objekte(Aobj und Bobj) zu reagieren, die &quot;im Prinzip&quot; das gleiche sind.</p>
<p>Benutze lieber virtuelle Funktionen und somit Laufzeit-Polymorphie. Dann können die Objekte selbst entscheiden, ob sie spezialisiert sein wollen oder nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1748938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1748938</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Fri, 24 Jul 2009 14:19:18 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Fri, 24 Jul 2009 17:12:49 GMT]]></title><description><![CDATA[<p>Schau dir mal <a href="http://www.boost.org/doc/libs/1_39_0/libs/type_traits/doc/html/boost_typetraits/reference/is_base_of.html" rel="nofollow">boost::is_base_of&lt;&gt;</a> an. Damit und mit dem Delegieren der Funktion an ein partiell spezialisiertes Functortemplate (Funktionstemplate kann man nicht partiell spezialisieren, nur überladen) wird sich was passendes bauen lassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1749047</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1749047</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 24 Jul 2009 17:12:49 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Sat, 25 Jul 2009 10:27:46 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Schau dir mal <a href="http://www.boost.org/doc/libs/1_39_0/libs/type_traits/doc/html/boost_typetraits/reference/is_base_of.html" rel="nofollow">boost::is_base_of&lt;&gt;</a> an. Damit und mit dem Delegieren der Funktion an ein partiell spezialisiertes Functortemplate (Funktionstemplate kann man nicht partiell spezialisieren, nur überladen) wird sich was passendes bauen lassen.</p>
</blockquote>
<p>Ehrlich gesagt verstehe ich noch nicht genug von der Materie, um das jetzt verstanden zu haben. Ich werde mich mal in das Thema einarbeiten.</p>
<p>Danke an alle Tippgeber!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1749320</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1749320</guid><dc:creator><![CDATA[Templateanfänger]]></dc:creator><pubDate>Sat, 25 Jul 2009 10:27:46 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Mon, 27 Jul 2009 11:55:13 GMT]]></title><description><![CDATA[<p>Hallo,<br />
das mit der Template Metaprogrammierung ist ziemlich komplex, deshalb die späte Antwort. Ich habe da mal was mit is_base_of gebastelt und das funktioniert auch wie gewünscht:</p>
<pre><code class="language-cpp">class Base{};

class A: public Base {};

class B: public A{};

class C: public Base{};

template&lt;class T, bool b&gt; void foo(T t, const boost::integral_constant&lt;bool, b&gt;&amp;);

template&lt;class T&gt; void foo(T a, const boost::true_type&amp;){
  cout&lt;&lt;&quot;Auf A spezialisiert&quot;&lt;&lt;endl;
  // Code verwendet immer static_cast&lt;A&gt;(a)
}

template&lt;class T&gt; void foo(T t, const boost::false_type&amp;)
{
  cout&lt;&lt;&quot;Unspezialisiert&quot;&lt;&lt;endl;
}

template&lt;class T&gt; void foo_caller(T t){
  foo(t, typename boost::is_base_of&lt;A,T&gt;());
}

int main()
{
  A a;
  B b;
  C c;
  int d;
  foo_caller(a);  // Spezialisiert auf A
  foo_caller(b);  // Spezialisiert auf A
  foo_caller(c);  // Unspezialisiert
  foo_caller(d);  // Unspezialisiert
}
</code></pre>
<p>Wenn ich jetzt aber eine weitere Spezialisierung hinzufügen will, stehe ich vor dem Problem, dass is_base_of nur zwei Werte haben kann, true oder false. Um mehr als eine Spezialisierung unterscheiden zu können, habe ich daran gedacht, so eine Art Bitset zu verwenden, ungefähr so:</p>
<pre><code class="language-cpp">template&lt;class T&gt; void foo_caller(T t){
  foo(t, typename boost::is_base_of&lt;A,T&gt;(), typename boost::is_base_of&lt;Base,T&gt;());
}
</code></pre>
<p>Das könnte und sollte man natürlich nochmals in einer Unterfunktion a la get_most_specialized_base&lt;typename T&gt;::type verstecken, aber das Prinzip bleibt das selbe.</p>
<p>Jedoch kommt mir das ziemlich umständlich vor, ich bin aber mit dieser Templateprogrammierung wie gesagt noch nicht so weit fortgeschritten, deshalb weiß ich nicht, ob es da bessere Methoden gibt. Hat da jemand einen Tipp für mich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750231</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750231</guid><dc:creator><![CDATA[Templateanfänger]]></dc:creator><pubDate>Mon, 27 Jul 2009 11:55:13 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Mon, 27 Jul 2009 13:24:51 GMT]]></title><description><![CDATA[<p>du willst also im Grunde eine template-basierte Abfrage, Pseudocode:</p>
<pre><code>foo (T):
  if A baseof T
    fooA(T)
  else if B baseof T
    fooB(T)
  else if C baseof T
    fooC(T)
  else 
    fooStandard(T)
</code></pre>
<p>Die Lösung wären Funktoren, die sind mit boost relativ leicht zu bauen. Folgender Ansatz:</p>
<pre><code class="language-cpp">template &lt;typename pred, typename A, typename B&gt;
struct Select;

template &lt;tyename A, typename B&gt;
struct Select&lt;boost::true_t, A, B&gt;
{
  typedef A type; //fuer true
};

template &lt;tyename A, typename B&gt;
struct Select&lt;boost::false_t, A, B&gt;
{
  typedef B type; //fuer false
};
</code></pre>
<p>Dann ist das Ganze für einen Typ recht einfach zu machen:</p>
<pre><code class="language-cpp">struct funA
{ 
  void operator()(A* pa); 
};
template&lt;class T&gt;
struct funStandard
{ 
  void operator()(T* pt);
};

template&lt;class T&gt;
void foo(T* pt)
{
  typedef Select&lt;boost::is_base_of&lt;A, T&gt;::type
                 funA,
                 funStandard&lt;T&gt; &gt;::type funType;
  funType functor;
  functor(T);
}
</code></pre>
<p>für mehrere wirds dann nur wenig komplizierter:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
void foo(T* pt)
{
  typedef Select&lt;boost::is_base_of&lt;A, T&gt;::type, funA,
          Select&lt;boost::is_base_of&lt;B, T&gt;::type, funB,
          Select&lt;boost::is_base_of&lt;C, T&gt;::type, funC,
                 funStandard&lt;T&gt; &gt;::type &gt;::type &gt;::type funType;
  funType functor;
  functor(T);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1750249</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750249</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 27 Jul 2009 13:24:51 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Mon, 27 Jul 2009 12:53:54 GMT]]></title><description><![CDATA[<p>Ja, das ist es was ich suchte. Und viel kürzer und eleganter als mein 60 Zeilen Monstrum, das ich mir dafür gebastelt habe <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 />
Dankeschön!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750264</guid><dc:creator><![CDATA[Templateanfänger]]></dc:creator><pubDate>Mon, 27 Jul 2009 12:53:54 GMT</pubDate></item><item><title><![CDATA[Reply to Templatespezialisierung und abgeleitete Klassen on Mon, 27 Jul 2009 15:06:53 GMT]]></title><description><![CDATA[<p>Man kann natürlich den ganzen boost::is_base_of krams noch wegkapseln:</p>
<pre><code class="language-cpp">template &lt;class Base, class BaseFun, class Else, class T = typename Else::T_type&gt;
struct ApplyIfInherits
{
  typedef T T_type;
  typedef Select&lt;boost::is_base_of&lt;Base, T&gt;::type, BaseFun, Else&gt;::type FuncType;

  void operator() (T* pt)
  {
    FuncType func;
    func(pt);
  }
};

//struct funA usw. wie oben
template&lt;typename T&gt;
void foo(T* pt)
{
  ApplyIfInherits&lt;A, funA,
  ApplyIfInherits&lt;B, funB,
  ApplyIfInherits&lt;C, funC,
  ApplyIfInherits&lt;D, funD, 
                     funStandard&lt;T&gt;, T&gt; &gt; &gt; &gt; functor;
  return functor(pt);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1750354</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750354</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 27 Jul 2009 15:06:53 GMT</pubDate></item></channel></rss>