<?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[Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung]]></title><description><![CDATA[<p>Hallo die Runde.</p>
<p>Zum vorausgegangenen Thread Metaprogrammierung wollte ich hier noch mal Beispiele bringen mit Praxisbezug. Um den Post nicht untergehen zu lasen habe ich noch mal ein eigenen Thread eröffnet.</p>
<p>Generell sehe ich in den Templates eine sehr mächtiges Werkzeug das einen viel Arbeit ersparen kann und setze diese so oft wie möglich ein. Fangen wir aber mal an.</p>
<p>Beispiel 1</p>
<p>Ich habe hier viele Objekte die alle die gleiche Basis haben. Dazu gibt es eine Liste in der die Objecte über das Base Objekt in X-beliebiger Reihenfolge gespeichert werden.</p>
<pre><code class="language-cpp">class ObjectA : public ObjectBase;
class ObjectB : public ObjectBase;
class ObjectC : public ObjectBase;
usw.

typedef std::list&lt;ObjectBase*&gt;	tObjectList;
</code></pre>
<p>Zur Laufzeit Spielt es keine Rolle was und in welcher Reihenfolge diese Objekte gespeichert sind. Nur wenn man das Bearbeitungsfenster schließt, müssen alle gleichen Objekte in eigen Container gespeichert werden. Etwa so:</p>
<pre><code class="language-cpp">for(tObjectList::iterator Iter = ObjectList.begin();
      Iter != ObjectList.end();
     ++Iter)
{
	if(Iter == ObjectA)
	{
		AobjectList.push_back(*Iter);
	}
	else if (Iter == ObjectB)
	....
	else if(Iter == ObjectC)
	....
	usw.
}
</code></pre>
<p>Das finde ich aber nicht sehr schön, schlecht zum erweitern und macht bei vielen verschiedenen Objekten auch reichlich Arbeit. Auch kann man diese Methode nicht teilen, also wenn man nur ObjectA und ObjectB haben will. Wie hilft uns da ein Template?</p>
<p>Zerteilen wir mal die vorgaben:<br />
a. Wir haben eine Quellen Liste<br />
b. Wir haben eine Ziel Liste<br />
c. Die Ziel Liste kennt den Objekt Type</p>
<p>Machen wir mal ein Template daraus. (Geschwindigkeit spielt an dieser Stelle keine Rolle)</p>
<pre><code class="language-cpp">template&lt; typename src_list, typename des_list&gt;
void findAndFill(const src_list &amp;SrcList, des_list &amp;DesList)
{
	typedef typename des_list::value_type 	tZielObject;

	for(src_list::const_iterator Iter = SrcList.begin();
		Iter != SrcList.end();
		++Iter)
	{
		if(typeid(tZielObject) == typeid(**Iter))
	            {
			DesList.push_back( static_cast&lt;tZielObject*&gt;(*Iter) );
		}
	}
}
</code></pre>
<p>Und Diese Funktion kann man dann einfach nutzen.</p>
<pre><code class="language-cpp">tObjectList	ObjectListe;

tObjectAList 	ObjectAList;
tObjectBList	ObjectBList;

findAndFill(ObjectListe, ObjectAList);
findAndFill(ObjectListe, ObjecteBList);
</code></pre>
<p>So sieht schon besser aus, einfach zu schreiben und Flexibel oder nicht? <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>Beispiel 2 – Zweckentfremden von Spezialisierung</p>
<p>Serialisiere – Aha, gibt es Tonnenweise Librarys dafür..... puh, habe mir auch einige angeschaut, aber richtig was Passendes habe ich nicht gefunden. Ich will die Daten in einer XML Ähnlichen Syntax schreiben und lesen. Und so wenig Aufwand beim Programmieren haben. Bin ja Faul. Geben wir mal eine Datensatz vor.</p>
<pre><code class="language-cpp">class ObjectFarbe;
class ObjectKreis;
class ObjectRecheck;

class ObjectSet
{
	char			*pName;
	bool			Flag;
	ObjectFarbe		Farbe;
	std::list&lt;Kreis&gt;	Kreise;
	std::list&lt;Rechteck&gt;	Rechtecke;
};
</code></pre>
<p>Jedem Objekt geben wir eine Schnittstelle für die Serialisierung und zwar eine für Lesen und Schreiben. Das ist aber noch kein Hexenwerk. Gibt schon librarays die so was machen.</p>
<pre><code class="language-cpp">template&lt; typename archiv &gt;
archiv&amp; serialisie(archiv &amp;Archiv)
{
	return Archiv.attribute(„Name“, pName)
		.attribute(„Flag“, Flag)
		.element(Farbe)
		.elementContainer(Kreise)
		.elementContainer(Rechteck);
}
</code></pre>
<p>uns als Datei soll so was rauskommen.</p>
<pre><code class="language-cpp">&lt;Set  Name=“Name“ Flag=“True“&gt;
    &lt;/Farbe  Rot=“1“ Blau=“2“&gt;
    &lt;/Kreis Durchmesser=“1“&gt;
    &lt;/Kreis Durchmesser=“2“&gt;
    &lt;/Rechteck Groesse=“10“&gt;
&lt;/Set&gt;
</code></pre>
<p>So weit so gut. Die Attribute werden in den Archiv Classen auch über Template Funktionen Abgebildete sollen aber nicht Bestandteil der Diskussion sein. Sondern die „element“ und „elementContainer“ Funktion.<br />
Frage: Woher wissen die Archiv Classen was für Namen die Element haben? Bei den Farben Element gibt es mehr Möglichkeiten aber wie macht löst man das mit den Containern?<br />
Genau hier scheitern die vielen Librarys.</p>
<p>Dazu benutze ich eine Hilfe. Man Ahnt es schon es ist eine Template Struktur.</p>
<pre><code class="language-cpp">template&lt; typename element &gt;
struct sElementName
{
	static const char * pElementName;
};
</code></pre>
<p>Wie sieht jetzt die Funktion „elementContainer“ aus.</p>
<pre><code class="language-cpp">template&lt; typename container &gt;
ArchivOut&amp; elementContainer(const container &amp;ObjectList)
{
	typedef sElementName&lt;container::value_type&gt;	tElementName;

	for(container::const_iterator Iter = ObjectList.begin();
		Iter != ObjectList.end();
		++Iter)
	{
		Out &lt;&lt; „&lt;“ &lt;&lt;  tElementName::pName;
		Iter-&gt; serialisie(*this);
		Out &lt;&lt; „&lt;/&gt; &lt;&lt; tElementname::pName;
	}
	return *this;
}
</code></pre>
<p>Jetzt kann der Compiler jeden Element einen Eindeutigen Namen zuordnen. Weil für jedes Element Objekt eine Eindeutige Hils-struktur erzeugt wird.<br />
Zum Linken fehlt aber noch was. Denn so steht jetzt eigentlich der Name? Dieses Packe ich in die Source Datei von den Element, das sieht so aus.</p>
<pre><code class="language-cpp">farbe.cpp
template&lt;&gt; sElementName&lt;ObjectFarbe&gt;::pName = „Farbe“;

kreis.cpp
template&lt;&gt; sElementName&lt;ObjectKreis&gt;::pName = „Kreis“;

usw.
</code></pre>
<p>So das ist meine Lösung der Serialisierung. Hat da jemand Einwände? Immer her damit.</p>
<p>Sind eigentlich solche Beispiel Interessant für euch? Hätte da noch ein Beispiel einer Undo/Redo Strategie. <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>Lichtlein</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/271721/praxis-beispiel-template-metaprogrammierung</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 06:31:29 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/271721.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 02 Aug 2010 20:35:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Mon, 02 Aug 2010 20:35:11 GMT]]></title><description><![CDATA[<p>Hallo die Runde.</p>
<p>Zum vorausgegangenen Thread Metaprogrammierung wollte ich hier noch mal Beispiele bringen mit Praxisbezug. Um den Post nicht untergehen zu lasen habe ich noch mal ein eigenen Thread eröffnet.</p>
<p>Generell sehe ich in den Templates eine sehr mächtiges Werkzeug das einen viel Arbeit ersparen kann und setze diese so oft wie möglich ein. Fangen wir aber mal an.</p>
<p>Beispiel 1</p>
<p>Ich habe hier viele Objekte die alle die gleiche Basis haben. Dazu gibt es eine Liste in der die Objecte über das Base Objekt in X-beliebiger Reihenfolge gespeichert werden.</p>
<pre><code class="language-cpp">class ObjectA : public ObjectBase;
class ObjectB : public ObjectBase;
class ObjectC : public ObjectBase;
usw.

typedef std::list&lt;ObjectBase*&gt;	tObjectList;
</code></pre>
<p>Zur Laufzeit Spielt es keine Rolle was und in welcher Reihenfolge diese Objekte gespeichert sind. Nur wenn man das Bearbeitungsfenster schließt, müssen alle gleichen Objekte in eigen Container gespeichert werden. Etwa so:</p>
<pre><code class="language-cpp">for(tObjectList::iterator Iter = ObjectList.begin();
      Iter != ObjectList.end();
     ++Iter)
{
	if(Iter == ObjectA)
	{
		AobjectList.push_back(*Iter);
	}
	else if (Iter == ObjectB)
	....
	else if(Iter == ObjectC)
	....
	usw.
}
</code></pre>
<p>Das finde ich aber nicht sehr schön, schlecht zum erweitern und macht bei vielen verschiedenen Objekten auch reichlich Arbeit. Auch kann man diese Methode nicht teilen, also wenn man nur ObjectA und ObjectB haben will. Wie hilft uns da ein Template?</p>
<p>Zerteilen wir mal die vorgaben:<br />
a. Wir haben eine Quellen Liste<br />
b. Wir haben eine Ziel Liste<br />
c. Die Ziel Liste kennt den Objekt Type</p>
<p>Machen wir mal ein Template daraus. (Geschwindigkeit spielt an dieser Stelle keine Rolle)</p>
<pre><code class="language-cpp">template&lt; typename src_list, typename des_list&gt;
void findAndFill(const src_list &amp;SrcList, des_list &amp;DesList)
{
	typedef typename des_list::value_type 	tZielObject;

	for(src_list::const_iterator Iter = SrcList.begin();
		Iter != SrcList.end();
		++Iter)
	{
		if(typeid(tZielObject) == typeid(**Iter))
	            {
			DesList.push_back( static_cast&lt;tZielObject*&gt;(*Iter) );
		}
	}
}
</code></pre>
<p>Und Diese Funktion kann man dann einfach nutzen.</p>
<pre><code class="language-cpp">tObjectList	ObjectListe;

tObjectAList 	ObjectAList;
tObjectBList	ObjectBList;

findAndFill(ObjectListe, ObjectAList);
findAndFill(ObjectListe, ObjecteBList);
</code></pre>
<p>So sieht schon besser aus, einfach zu schreiben und Flexibel oder nicht? <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>Beispiel 2 – Zweckentfremden von Spezialisierung</p>
<p>Serialisiere – Aha, gibt es Tonnenweise Librarys dafür..... puh, habe mir auch einige angeschaut, aber richtig was Passendes habe ich nicht gefunden. Ich will die Daten in einer XML Ähnlichen Syntax schreiben und lesen. Und so wenig Aufwand beim Programmieren haben. Bin ja Faul. Geben wir mal eine Datensatz vor.</p>
<pre><code class="language-cpp">class ObjectFarbe;
class ObjectKreis;
class ObjectRecheck;

class ObjectSet
{
	char			*pName;
	bool			Flag;
	ObjectFarbe		Farbe;
	std::list&lt;Kreis&gt;	Kreise;
	std::list&lt;Rechteck&gt;	Rechtecke;
};
</code></pre>
<p>Jedem Objekt geben wir eine Schnittstelle für die Serialisierung und zwar eine für Lesen und Schreiben. Das ist aber noch kein Hexenwerk. Gibt schon librarays die so was machen.</p>
<pre><code class="language-cpp">template&lt; typename archiv &gt;
archiv&amp; serialisie(archiv &amp;Archiv)
{
	return Archiv.attribute(„Name“, pName)
		.attribute(„Flag“, Flag)
		.element(Farbe)
		.elementContainer(Kreise)
		.elementContainer(Rechteck);
}
</code></pre>
<p>uns als Datei soll so was rauskommen.</p>
<pre><code class="language-cpp">&lt;Set  Name=“Name“ Flag=“True“&gt;
    &lt;/Farbe  Rot=“1“ Blau=“2“&gt;
    &lt;/Kreis Durchmesser=“1“&gt;
    &lt;/Kreis Durchmesser=“2“&gt;
    &lt;/Rechteck Groesse=“10“&gt;
&lt;/Set&gt;
</code></pre>
<p>So weit so gut. Die Attribute werden in den Archiv Classen auch über Template Funktionen Abgebildete sollen aber nicht Bestandteil der Diskussion sein. Sondern die „element“ und „elementContainer“ Funktion.<br />
Frage: Woher wissen die Archiv Classen was für Namen die Element haben? Bei den Farben Element gibt es mehr Möglichkeiten aber wie macht löst man das mit den Containern?<br />
Genau hier scheitern die vielen Librarys.</p>
<p>Dazu benutze ich eine Hilfe. Man Ahnt es schon es ist eine Template Struktur.</p>
<pre><code class="language-cpp">template&lt; typename element &gt;
struct sElementName
{
	static const char * pElementName;
};
</code></pre>
<p>Wie sieht jetzt die Funktion „elementContainer“ aus.</p>
<pre><code class="language-cpp">template&lt; typename container &gt;
ArchivOut&amp; elementContainer(const container &amp;ObjectList)
{
	typedef sElementName&lt;container::value_type&gt;	tElementName;

	for(container::const_iterator Iter = ObjectList.begin();
		Iter != ObjectList.end();
		++Iter)
	{
		Out &lt;&lt; „&lt;“ &lt;&lt;  tElementName::pName;
		Iter-&gt; serialisie(*this);
		Out &lt;&lt; „&lt;/&gt; &lt;&lt; tElementname::pName;
	}
	return *this;
}
</code></pre>
<p>Jetzt kann der Compiler jeden Element einen Eindeutigen Namen zuordnen. Weil für jedes Element Objekt eine Eindeutige Hils-struktur erzeugt wird.<br />
Zum Linken fehlt aber noch was. Denn so steht jetzt eigentlich der Name? Dieses Packe ich in die Source Datei von den Element, das sieht so aus.</p>
<pre><code class="language-cpp">farbe.cpp
template&lt;&gt; sElementName&lt;ObjectFarbe&gt;::pName = „Farbe“;

kreis.cpp
template&lt;&gt; sElementName&lt;ObjectKreis&gt;::pName = „Kreis“;

usw.
</code></pre>
<p>So das ist meine Lösung der Serialisierung. Hat da jemand Einwände? Immer her damit.</p>
<p>Sind eigentlich solche Beispiel Interessant für euch? Hätte da noch ein Beispiel einer Undo/Redo Strategie. <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>Lichtlein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935339</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935339</guid><dc:creator><![CDATA[Lichtlein]]></dc:creator><pubDate>Mon, 02 Aug 2010 20:35:11 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Mon, 02 Aug 2010 23:22:36 GMT]]></title><description><![CDATA[<p>Zu Beispiel 1:<br />
Das ist in meinen Augen nicht wirklich Metaprogrammierung.<br />
Eine Grenze zu definieren ist zwar schwierig, aber für mich ist<br />
das einfache Template-Programmierung.</p>
<p>Außerdem ist das Design-technisch etwas dirty (finde ich).<br />
Wenn ich weiß, dass ich die Typen anders behandeln muss, dann verwalte ich<br />
sie auch separat.</p>
<p>Zu Beispiel 2:<br />
Das ist ja quasi ein type trait (oder?)<br />
aber (wie ich denke) sinnvoll angewendet...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935394</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935394</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Mon, 02 Aug 2010 23:22:36 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 06:47:58 GMT]]></title><description><![CDATA[<p>Zu eins:<br />
Dazu müsste man wohl erst mal ganz genau Definieren was Metaprogrammierung ist und wie man sie erkennen kann. Gibt es nicht Irgendwo eine Liste die man abhacken kann und man dann weiß ob oder ob nicht? <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>Zu zwei:<br />
Denke da hast Du schon recht das es ein erweitertes &quot;Type trait&quot; ist.</p>
<p>Übrigens zum zweiten Beispiel. Da habe ich an Anfang mal ein wenig mit Type Listen Experimentiert. Hat so auch ganz gut Funktioniert.</p>
<p>Sah in etwa so aus:</p>
<pre><code class="language-cpp">class ObjectSet
{

typedef tTypeList&lt; char*, tTypeList&lt; bool, tTypeList&lt; ObjectFarbe......
     tObjectSetTypeList;    

template&lt; typename archiv &gt;
archiv&amp; serialisie(archiv &amp;Archiv)
{
    return Archiv.typelist&lt;tObjectSetTypeList&gt;(mContent);
}

tObjectSetTypeList mContent;
};
</code></pre>
<p>Ist schon ein wenig her und ich weiß nicht wieso ich das dann nicht benutzt habe. Glaube es wahr einfach nur Unüberschichtlich auf den Inhalt zuzugreifen und nicht wirklich gut zu Lesen.</p>
<p>Siehe hier:</p>
<pre><code class="language-cpp">ObjectFarbe objectFarbe() const { return field[3]; }
void setObjectFarbe(const ObjectFarbe &amp;Farbe) { field[3] = Farbe; }
</code></pre>
<p>Nett so besonders bei Klassen die mehr als 10 Member Variablen haben.</p>
<p>Lichtlein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935444</guid><dc:creator><![CDATA[Lichtlein]]></dc:creator><pubDate>Tue, 03 Aug 2010 06:47:58 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 08:37:00 GMT]]></title><description><![CDATA[<p>@Lichtlein</p>
<p>Hättest du eventuell Lust, diesen Post (gern auch in längerer Form mit mehr Beispielen) als Artikel im C++ Magazin zu veröffentlichen? Kurze E-Mail an redaktion at c-plusplus punkt de, falls du Interesse hast <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/1935479</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935479</guid><dc:creator><![CDATA[GPC]]></dc:creator><pubDate>Tue, 03 Aug 2010 08:37:00 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 15:41:28 GMT]]></title><description><![CDATA[<p>Ich halte den Code für Quatsch, sorry.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935661</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 03 Aug 2010 15:41:28 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 16:24:12 GMT]]></title><description><![CDATA[<p>Ich auch mehr oder weniger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935693</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935693</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 03 Aug 2010 16:24:12 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 16:24:44 GMT]]></title><description><![CDATA[<p>Besonders Beispiel 1: RTTI ist doch so ziemlich das genaue Gegenteil von TMP. Für sowas hat man extra Traits entwickelt, um auf solchen Spaß wie typeid und dynamic_cast zu verzichten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935694</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935694</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Tue, 03 Aug 2010 16:24:44 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 17:26:09 GMT]]></title><description><![CDATA[<p>Sowas würde ich auch nicht unbedingt als klassische Metaprogrammierung ansehen, obwohl einige TMP-Elemente vorhanden sind. Typische (teilweise Extrem-)Beispiele sind Alexandrescus <em>Modern C++ Design</em> oder einige Bibliotheken aus Boost.</p>
<p>Ad aCTa schrieb:</p>
<blockquote>
<p>Für sowas hat man extra Traits entwickelt, um auf solchen Spaß wie typeid und dynamic_cast zu verzichten.</p>
</blockquote>
<p>Finde mal die Typ-ID zur Laufzeit mittels Traits heraus. Lichtleins Ansatz geht in die Richtung von &quot;Multimethoden&quot; (dynamisches Dispatching), er könnte allerdings noch generischer und effizienter sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935717</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935717</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 03 Aug 2010 17:26:09 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 20:10:55 GMT]]></title><description><![CDATA[<p>So wie es aussieht kommt der Code wohl nicht so gut an. Hat sich dann wohl als Artikel erledigt. <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>Aber noch mal zurück zum Thema.</p>
<p>Beispiel 1</p>
<p>Sollte man es sich nicht so einfach wie möglich machen und die verfügbaren Mittel je nach Anwendungszweck einsetzen? Zu der besagten Liste, diese wird beim Öffnen eines Fenster aus einen Datensatz erzeugt. Beim bearbeiten werden neue Objekte in diese Liste aufgenommen, gelöscht und geändert. Ist dieser Prozess beendet und das Fenster wird geschlossen so werden aus dieser Liste wie gesagt die Verschiedenen Objektetypen geholt und in andere Container gepackt. Also 1 mal wird auf RTTI zurückgegriffen. Was soll daran schlecht sein? &quot;Effizienter&quot; muss es auch nicht sein. Zeit Spielt schlicht keine Rolle.</p>
<p>Noch ein kleiner Hinweis. Die besagte Liste ist eigentlich real ein Komplexer Struktur-Tree, der für die Bearbeitung von max. 1 Millionen Objekten ausgelegt ist. In diesen Fall wird Sie &quot;zweckentfremdet&quot;.</p>
<p>Beispiel 2<br />
Wie ich in meinen zweiten Post geschrieben habe, habe ich einmal einen XML Ähnlichen Stream Prototypen geschrieben der auf den Ideen vom &quot;Modernes C++ Design&quot; zurückgreift. (Typelisten) Und wie ich schon beschrieben habe, das ganze ist nicht mehr Leserlich! Man kann den Code einfach nicht Warten. Und nur weil es Cool ist (Ja es ist Cool, wenigstens wenn man es mal Programmiert <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="😉"
    /> )und funktioniert sollte man es nicht einsetzen, wenn man den Code nicht Pflegen kann. Meine Meinung.<br />
Und es würde mich freuen wenn mir Jemand ein XML Ähnlichen Stream zeigt der in der Benutzung so einfach ist wie von mir beschrieben.</p>
<p>Lichtlein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935805</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935805</guid><dc:creator><![CDATA[Lichtlein]]></dc:creator><pubDate>Tue, 03 Aug 2010 20:10:55 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 23:38:23 GMT]]></title><description><![CDATA[<p>Zum Beispiel 1:<br />
Was spricht gegen einen klassischen Ansatz ala:</p>
<pre><code class="language-cpp">#include&lt;iostream&gt;
#include&lt;vector&gt;
#include&lt;list&gt;
#include&lt;deque&gt;

class A;
class B;
class C;

class Collections{

public:
        std::vector&lt;A*&gt; vecA;
        std::list&lt;B*&gt; vecB;
        std::deque&lt;C*&gt; vecC;
};

class A {
public:
        int i;

        virtual void assign(Collections&amp; col){
                col.vecA.push_back(this);
        }

        virtual ~A(){}
};

class B : public A {
        virtual void assign(Collections&amp; col){
                col.vecB.push_back(this);
        }
};

class C : public A {
        virtual void assign(Collections&amp; col){
                col.vecC.push_back(this);
        }
};

int main(){
        A a1;
        a1.i = 1;
        A a2;
        a2.i = 2;
        B b1;
        b1.i = 3;
        B b2;
        b2.i = 4;
        C c1;
        c1.i = 5;
        C c2;
        c2.i = 6;

        std::vector&lt;A*&gt; vec;
        vec.push_back(&amp;a1);
        vec.push_back(&amp;b1);
        vec.push_back(&amp;c1);
        vec.push_back(&amp;a2);
        vec.push_back(&amp;b2);
        vec.push_back(&amp;c2);

        Collections col;
        for(std::vector&lt;A*&gt;::iterator it = vec.begin(); it!=vec.end(); ++it){
                (*it)-&gt;assign(col);
        }
        std::cout &lt;&lt; &quot;A:&quot; &lt;&lt; std::endl;
        for(std::vector&lt;A*&gt;::iterator it = col.vecA.begin(); it!=col.vecA.end(); ++it){
                std::cout &lt;&lt; (*it)-&gt;i &lt;&lt; std::endl;
        }
        std::cout &lt;&lt; &quot;B:&quot; &lt;&lt; std::endl;
        for(std::list&lt;B*&gt;::iterator it = col.vecB.begin(); it!=col.vecB.end(); ++it){
                std::cout &lt;&lt; (*it)-&gt;i &lt;&lt; std::endl;
        }
        std::cout &lt;&lt; &quot;C:&quot; &lt;&lt; std::endl;
        for(std::deque&lt;C*&gt;::iterator it = col.vecC.begin(); it!=col.vecC.end(); ++it){
                std::cout &lt;&lt; (*it)-&gt;i &lt;&lt; std::endl;
        }
        return 0;
}
</code></pre>
<blockquote>
<p>A:<br />
1<br />
2<br />
B:<br />
3<br />
4<br />
C:<br />
5<br />
6</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1935867</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935867</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Tue, 03 Aug 2010 23:38:23 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Tue, 03 Aug 2010 23:44:19 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Zum Beispiel 1:<br />
Was spricht gegen einen klassischen Ansatz ala:</p>
</blockquote>
<p>Das ist eine gute Frage, aber noch nicht DIE Frage.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935869</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935869</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 03 Aug 2010 23:44:19 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 00:18:55 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>XSpille schrieb:</p>
<blockquote>
<p>Zum Beispiel 1:<br />
Was spricht gegen einen klassischen Ansatz ala:</p>
</blockquote>
<p>Das ist eine gute Frage, aber noch nicht DIE Frage.</p>
</blockquote>
<p>Was spricht gegen Templates?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935870</guid><dc:creator><![CDATA[Templates?]]></dc:creator><pubDate>Wed, 04 Aug 2010 00:18:55 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 02:29:58 GMT]]></title><description><![CDATA[<p>Templates? schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>XSpille schrieb:</p>
<blockquote>
<p>Zum Beispiel 1:<br />
Was spricht gegen einen klassischen Ansatz ala:</p>
</blockquote>
<p>Das ist eine gute Frage, aber noch nicht DIE Frage.</p>
</blockquote>
<p>Was spricht gegen Templates?</p>
</blockquote>
<p>Natürlich kannst du auch Abfragen ala</p>
<pre><code>if(typA){
...
} else if(typB){
...
} else if(typC){
...
}
</code></pre>
<p>machen und was anderes macht er ja quasi nicht.<br />
Er hat genau genommen mehrere Schleifen mit einem if drin,<br />
die er durch Templates auslagert.<br />
Abgesehen davon geht er dadurch noch mehrfach durch die Liste geht.<br />
Aber der Punkt ist (wohl) relativ unerheblich.</p>
<p>Um (u. a.) genau solche Konstrukte zu vermeiden, bietet sich ja<br />
Objektorientierung an.<br />
Klar kann man jedes C++ in ein C Programm umwandeln und durch die<br />
Templates vereinfacht er sich quasi das Schreiben eines 'C-Programms'<br />
(zumindest an dieser Stelle).<br />
Zudem sind diese Konstrukte schwerer lesbar als der OO-Ansatz (vielleicht Geschmacksache)</p>
<p>Ich glaube, ich würde die Objekte schon während der gesamten Zeit getrennt<br />
verwalten und ein anderes Objekt drum wrappen, damit ich über<br />
alle Elemente iterieren kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935872</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935872</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Wed, 04 Aug 2010 02:29:58 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 02:49:01 GMT]]></title><description><![CDATA[<p>bin nicht so der c++ kenner, aber blähen templates die größe des kompilates nicht extrem auf?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935873</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935873</guid><dc:creator><![CDATA[no_c0de]]></dc:creator><pubDate>Wed, 04 Aug 2010 02:49:01 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 09:04:44 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/24036">@XSpille</a><br />
Danke.<br />
Mal ein richtiger Vorschlag wie man es besser/anders machen könnte. Ich habe Deine Idee mal ein wenig umgeformt so das man einzelne Werte aus der Liste abfragen kann.</p>
<pre><code class="language-cpp">template&lt; typename type &gt;
struct sSammler
{
    std::list&lt; type &gt;   mList;
};

struct sBase
{
    typedef void (*tFunc) ();
    template&lt; typename type &gt; void assign(sSammler&lt; type &gt; &amp;Sammler);

    virtual tFunc assignRefFun() { return (tFunc) 0; }
};

template&lt; typename t &gt;
struct sAssign : public sBase
{
    static void refFunc() {};
    virtual tFunc assignRefFun() { return &amp;refFunc; }
};

template&lt; typename type &gt; void sBase::assign(sSammler&lt; type &gt; &amp;Sammler)
{
    if(&amp;sAssign&lt;type&gt;::refFunc == assignRefFun())
    {
        Sammler.mList.push_back(*static_cast&lt;type*&gt;(this));
    }
}

struct sA : public sAssign&lt;sA&gt; {};
struct sB : public sAssign&lt;sB&gt; {};
struct sC : public sAssign&lt;sC&gt; {};

int main(int argc, char *argv[])
{
    typedef std::list&lt;sBase*&gt; tBases;

    tBases J;

    J.push_back(new sA);
    J.push_back(new sB);
    J.push_back(new sA);
    J.push_back(new sA);
    J.push_back(new sB);
    J.push_back(new sC);
    J.push_back(new sA);

    cout &lt;&lt; J.size() &lt;&lt; endl;

    sSammler&lt;sA&gt;  Sa;
    for(tBases::iterator Iter = J.begin(); Iter != J.end(); ++Iter)
    {
        (*Iter)-&gt;assign(Sa);
    }

    cout &lt;&lt; Sa.mList.size() &lt;&lt; endl;

    return EXIT_SUCCESS;
}
</code></pre>
<p>Ok das mit dem Pointer auf eine Funktion als Erkennung ist schon sehr Grenzwertig. Man könnte hier auch mit der TypeToInt Methode Arbeiten. Würde aber wieder mehr schreibaufwand bedeuten. (Mmmm vielleicht sollte ich in mein Projekt alles eine Type Id geben)</p>
<p>Bitte jetzt Steinigen. <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>Lichtlein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935975</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935975</guid><dc:creator><![CDATA[Lichtlein]]></dc:creator><pubDate>Wed, 04 Aug 2010 09:04:44 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 09:09:46 GMT]]></title><description><![CDATA[<p>no_c0de schrieb:</p>
<blockquote>
<p>bin nicht so der c++ kenner, aber blähen templates die größe des kompilates nicht extrem auf?</p>
</blockquote>
<p>Kommt drauf an, was man macht. Es kommt natürlich für jede unterschiedliche Templateinstanzierung eine neue Klasse/Funktion hinzu. Jedoch hätte man diese ja in der Regel auch ohne Templates schreiben müssen, um das gleiche zu erreichen.</p>
<p>Es gibt einige Extremfälle von Metaprogrammierung, wo man alle möglichen Programmabläufe durch den Compiler durchrechnen lässt. Dann hat man alle denkbaren Programmergebnisse im Compilat stehen, was natürlich extrem blähen kann (kann aber auch kürzer sein!). Dies sind dann aber wiederum die exotischen Fälle der Metaprogrammierung die in der Praxis niemand benutzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1935976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1935976</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 04 Aug 2010 09:09:46 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 10:43:12 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>no_c0de schrieb:</p>
<blockquote>
<p>bin nicht so der c++ kenner, aber blähen templates die größe des kompilates nicht extrem auf?</p>
</blockquote>
<p>Kommt drauf an, was man macht. Es kommt natürlich für jede unterschiedliche Templateinstanzierung eine neue Klasse/Funktion hinzu. Jedoch hätte man diese ja in der Regel auch ohne Templates schreiben müssen, um das gleiche zu erreichen.</p>
</blockquote>
<p>Ich würde eher sagen: ohne Templates würde man viele Probleme anders lösen.</p>
<p>Viel Code der durch Templates erzeugt wird ist 1:1 gleich für alle Template-Instanzierungen. Die meisten C++ Programmierer sind aber zu bequem solchen Code aus dem Template in z.B. eine Nicht-Template-Basisklasse rauszuziehen.</p>
<p>An vielen Stellen wird auch nur ein T* rumgereicht, oder vielleicht ein sizeof(T) verwendet, und sonst nix gemacht was für verschiedene T unterschiedlich wäre. Das sind alles Dinge wo man ohne Templates z.B. void-Zeiger verwendet hätte, bzw. Dinge wie sizeof(T) als Parameter mitgegeben/als Member abgespeichert.</p>
<p>Kurz: bei dem was ich als typischen Template-Code kenne, werden Programme definitiv unnötig aufgebläht. Der Begriff &quot;Template Bloat&quot; wurde ja nicht umsonst geprägt.<br />
Man kann Templates allerdings auch so einsetzen, dass der Template Bloat auf ein vernünftiges Mass reduziert wird.</p>
<p>Wobei vernünftig natürlich wieder sehr subjektiv und auch vom Programm/Einssatzzweck abhängig. Wenn irgend ein Game/Tool/... was auf modernen Rechnern laufen soll statt 500k statt 200k hat, ist mir das herzlich egal <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/1936027</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1936027</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 Aug 2010 10:43:12 GMT</pubDate></item><item><title><![CDATA[Reply to Praxis Beispiel &#x2F; Template &#x2F; Metaprogrammierung on Wed, 04 Aug 2010 11:59:49 GMT]]></title><description><![CDATA[<p>Zum Beispiel arbeiten Boosts Pointer-Container mit <code>void*</code> statt <code>T*</code> . Ist wahnsinnig praktisch beim Debuggen, wenn man nach den etlichen Indirektionsebenen immer noch nicht auf den konkreten Wert trifft... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
<p>Indirektion von <code>boost::ptr_map</code> (ohne Template-Parameter):</p>
<pre><code class="language-cpp">boost::ptr_map
boost::ptr_map_adapter
boost::ptr_container_detail::ptr_map_adapter_base
boost::ptr_container_detail::associative_ptr_container
boost::ptr_container_detail::reversible_ptr_container
std::map
</code></pre>
<p>Und dann steht man vor dem Nichts (genauer gesagt dem Zeiger darauf).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1936059</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1936059</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 04 Aug 2010 11:59:49 GMT</pubDate></item></channel></rss>