<?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[Polymorphie Adé]]></title><description><![CDATA[<p>Also da war gerade dieser Typ von Adobe und hat folgenden Code gezeigt:</p>
<pre><code class="language-cpp">class object_t {
public:
	template&lt; typename T &gt;
	object_t(T x) : self_(std::make_unique &lt; model &lt; T &gt;&gt; (std::move(x)))
	{}

	void draw(std::ostream&amp; out, size_t position) const
	{
		self_-&gt;draw_(out, position);
	}

	object_t(object_t &amp;&amp; other)
		: self_(std::move(other.self_))
	{}

private:
	object_t(const object_t&amp;);
	void operator=(const object_t&amp;);

	struct concept_t {
		virtual ~concept_t()
		{}

		virtual void draw_(std::ostream&amp;, size_t) const = 0;
	};

	template&lt; typename T &gt;
	struct model : concept_t {
		model(T x) : data_(std::move(x) )
		{}

		void draw_(std::ostream&amp; out, size_t position) const
		{
			data_.draw(out, position);
		}

		T data_;
	};

	std::unique_ptr&lt; const concept_t &gt; self_;
};

class class1 {
public:
	void draw(std::ostream&amp; out, size_t position) const 
	{
		out &lt;&lt; &quot;class1 :: draw\n&quot;;
	}
};

class class2 {
public:
	void draw(std::ostream&amp; out, size_t position) const
	{
		out &lt;&lt; &quot;class2 :: draw\n&quot;;
	}
};

int main(int argc, char* argv[])
{
	std::vector&lt; object_t &gt; objects;

	objects.emplace_back(class1());
	objects.emplace_back(class2());

	for (const auto&amp; object : objects) object.draw(std::cout, 0);

	return 0;
}
</code></pre>
<p>Und ich so, wtf? Das ist doch irgendwie ein Pimpl zusammengeworfen mit einem Handle zu einem konstanten Objekt = Supertoll?<br />
Und dann redet er davon, dass es keine Einschränkung wäre, dass Models Immutable wäre und von COW - Hauptsache ist, das eine Objekt, das irgendjemand referenziert, wird nicht verändert.<br />
Mal davon abgesehen, dass es wohl zu ekligsten Compilerfehlern führt, wenn das gegebene Objekt nicht die geforderte Schnittstelle erfüllt - wie kann das überhaupt praktikabel sein? Ich meine, das Model ist doch in den meisten Programmen dazu da, vom Programm selber oder dem Benutzer verändert zu werden. Wie kann man dann als Allheilmittel sagen: Da machen wir das Model konstant, dann haben wir auch keine Multithreading-Probleme?</p>
<p>Hat da jemand mehr Erfahrung und kann das in das rechte Licht rücken?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/319832/polymorphie-adé</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Jul 2026 19:42:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/319832.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 04 Sep 2013 20:09:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Polymorphie Adé on Wed, 04 Sep 2013 20:09:15 GMT]]></title><description><![CDATA[<p>Also da war gerade dieser Typ von Adobe und hat folgenden Code gezeigt:</p>
<pre><code class="language-cpp">class object_t {
public:
	template&lt; typename T &gt;
	object_t(T x) : self_(std::make_unique &lt; model &lt; T &gt;&gt; (std::move(x)))
	{}

	void draw(std::ostream&amp; out, size_t position) const
	{
		self_-&gt;draw_(out, position);
	}

	object_t(object_t &amp;&amp; other)
		: self_(std::move(other.self_))
	{}

private:
	object_t(const object_t&amp;);
	void operator=(const object_t&amp;);

	struct concept_t {
		virtual ~concept_t()
		{}

		virtual void draw_(std::ostream&amp;, size_t) const = 0;
	};

	template&lt; typename T &gt;
	struct model : concept_t {
		model(T x) : data_(std::move(x) )
		{}

		void draw_(std::ostream&amp; out, size_t position) const
		{
			data_.draw(out, position);
		}

		T data_;
	};

	std::unique_ptr&lt; const concept_t &gt; self_;
};

class class1 {
public:
	void draw(std::ostream&amp; out, size_t position) const 
	{
		out &lt;&lt; &quot;class1 :: draw\n&quot;;
	}
};

class class2 {
public:
	void draw(std::ostream&amp; out, size_t position) const
	{
		out &lt;&lt; &quot;class2 :: draw\n&quot;;
	}
};

int main(int argc, char* argv[])
{
	std::vector&lt; object_t &gt; objects;

	objects.emplace_back(class1());
	objects.emplace_back(class2());

	for (const auto&amp; object : objects) object.draw(std::cout, 0);

	return 0;
}
</code></pre>
<p>Und ich so, wtf? Das ist doch irgendwie ein Pimpl zusammengeworfen mit einem Handle zu einem konstanten Objekt = Supertoll?<br />
Und dann redet er davon, dass es keine Einschränkung wäre, dass Models Immutable wäre und von COW - Hauptsache ist, das eine Objekt, das irgendjemand referenziert, wird nicht verändert.<br />
Mal davon abgesehen, dass es wohl zu ekligsten Compilerfehlern führt, wenn das gegebene Objekt nicht die geforderte Schnittstelle erfüllt - wie kann das überhaupt praktikabel sein? Ich meine, das Model ist doch in den meisten Programmen dazu da, vom Programm selber oder dem Benutzer verändert zu werden. Wie kann man dann als Allheilmittel sagen: Da machen wir das Model konstant, dann haben wir auch keine Multithreading-Probleme?</p>
<p>Hat da jemand mehr Erfahrung und kann das in das rechte Licht rücken?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350371</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350371</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Wed, 04 Sep 2013 20:09:15 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Wed, 04 Sep 2013 20:14:13 GMT]]></title><description><![CDATA[<p>Das ist Type Erasure, wenn ich das richtig erkenne oO<br />
<a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure" rel="nofollow">http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350373</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350373</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Wed, 04 Sep 2013 20:14:13 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Wed, 04 Sep 2013 20:19:11 GMT]]></title><description><![CDATA[<p>Also mit der Technik die da angewandt wird, könnte ich ja vielleicht konform gehen, auch wenn das halt genau wie PIMPL zu einer Menge Schreibarbeit führt.<br />
Aber der springe Punkt in dem Vortrag war ja, dort einen CONST-Zeiger als injiziertes Pimpl zu benutzen, weil das macht das Multithreading einfacher... Im Vortrag selber benutzt er auch shared_ptr&lt;const T&gt;. Der springende Punkt ist doch, dass auch bei Adobe mehrere Views auf ein Model Zugriff haben, wenn die nun COW benutzen, dann würden die Views ja auch desynchronisieren, weil sie unterschiedliche Zeitzustände des Models anzeigen. Ich verstehe einfach nicht, wie man ein konstantes Model praktikabel umsetzen soll, ohne die gleichen Probleme zu lösen, die man auch mit dem Mutable-Model gehabt hätte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350374</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350374</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Wed, 04 Sep 2013 20:19:11 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Wed, 04 Sep 2013 20:27:19 GMT]]></title><description><![CDATA[<p>Jo, type erasure. std::function funktioniert so. Manchmal ist das so flexibler als mit Vererbung (hier ... naja).</p>
<p>Das mit const/immutable und COW verstehe ich nicht ganz, das const kann da genasogut entfernt werden. Gleich mit multithreading.</p>
<p>Vielleicht meinte er const=threadsafe, aber das lässt sich nicht so recht in Zusammenhang mit diesem Code bringen. Ok mal geraten:</p>
<pre><code class="language-cpp">objects[0] = class1()
</code></pre>
<p>ist fast(tm) threadsafe. Um ganz threadsafe zu sein müsste unique_ptr mit einem atomic&lt;model_t*&gt; implementiert sein. Deshalb wahrscheinlich COW. Man macht alles const=threadsafe. Um zu verändert kopiert man das Zeugs und steckt das veränderte dann wieder rein. Aber deine Beschreibung, kp.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350377</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350377</guid><dc:creator><![CDATA[ey jo]]></dc:creator><pubDate>Wed, 04 Sep 2013 20:27:19 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Wed, 04 Sep 2013 20:48:45 GMT]]></title><description><![CDATA[<p>Naja, mir ist ja eben nicht so ganz klar, aus welcher Perspektive seine Sicht auf die ganze Sache stattfindet. Ich denke eben gerade an GUI-Applikation und er hat da vorher von Task-Chains und Task-Graphen geredet etc..<br />
Es ging ihm dann vor allem darum, dass wenn mehrere Mutable-Referenzen auf ein Objekt draußen sind, dann kann an einer lokalen Stelle nicht darauf schließen wie es hier funktioniert, weil ein anderer Thread das Model zum gleichen Zeitpunkt verändern kann.<br />
Und ich kann mir diesen Ansatz wirklich überhaupt nicht praktikabel vorstellen, es sei denn, diese Objekte sind eher als Nachrichtenpakete zwischen Tasks in einem Threadpool zu verstehen.<br />
Es gibt doch nunmal einfach Problemstellungen, bei denen natürlicherweise mehrere &quot;weit entfernte&quot; Codestellen eine Mutable-Referenz (egal ob jetzt durch Zeiger, oder PIMPL/Handle/Type-Erasure-Superproxies) auf dasselbe Objekt im Speicher halten. Er sagt aber in dem Talk, er sei nicht davon überzeigt, dass Immutable irgendeine Einschränkung wäre.<br />
Diese Stelle des Vortrags war eben bei Going Native 2013 und das ganze beim Zeitstempel 3:43:30 unter der Überschrift &quot;No Raw Pointers&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350384</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350384</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Wed, 04 Sep 2013 20:48:45 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 13:11:21 GMT]]></title><description><![CDATA[<p>Ohne das jetzt überprüft zu haben: Es klingt nach Sean Parent. Da hatte ich schon einmal einen Vortrag von ihm zum Thema &quot;value semantics and concepts based polymorphism&quot; gesehen. COW kam auch drin vor. Und das Anwendungsbeispiel war ja relevant. Die haben mit dem Ansatz angeblich Photoshop eine komplett neue Implementierung von undo/redo spendiert. Das mit dem <code>const</code> da ist mir aber neu. Muss ich mir heute Abend mal reinziehen, wenn ich mehr Zeit habe.</p>
<p>&lt;OT&gt;<br />
Die Strousttrup-Vorträge hauen mich irgendwie auch nicht mehr vom Hocker. Hatte gestern da mal reingezappt und fragte mich, wie sinnig Konzepte (concepts) sind, die nur für genau eine Funktion aus &lt;algorithm&gt; gemacht wurden: Sortable, Mergable. Und die Verlagerung der Komplexität der Requirments aus std::merge nach Mergable war jetzt eine Leistung? &quot;Guckt mal, jetzt steht da nur noch requires Mergable&lt;...&gt;()&quot;. Toll, dafür hast du jetzt ein dickes unnützes Mergable-Konzept.<br />
&lt;/OT&gt;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350500</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 05 Sep 2013 13:11:21 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 13:33:10 GMT]]></title><description><![CDATA[<p>Ja, das war er glaube ich.<br />
War der Vortrag, von dem Du sprichst &quot;kostenlos sichtbar&quot;? Würde ich mir gerne anschauen. Ich glaube, er sagte auch, er würde noch einen weiteren Vortrag halten auf der diesjährigen Going Native, vielleicht geht er da nochmal genauer drauf ein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350515</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350515</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Thu, 05 Sep 2013 13:33:10 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 13:35:52 GMT]]></title><description><![CDATA[<p>die Videoqualität ist leider nicht so toll:<br />
<a href="http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent" rel="nofollow">http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350516</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350516</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 05 Sep 2013 13:35:52 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 14:08:38 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>und fragte mich, wie sinnig Konzepte (concepts) sind, die nur für genau eine Funktion aus &lt;algorithm&gt; gemacht wurden</p>
</blockquote>
<p>Genau so sinnig wie Funktionen die nur ein mal aufgerufen werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350527</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350527</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Thu, 05 Sep 2013 14:08:38 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 14:14:37 GMT]]></title><description><![CDATA[<p>Ich stimme kk hier zu. Ein concept und eine Funktion sind voellig unterschiedliche Dinge. Waehrend bei einer Funktion die Implementierung von aussen betrachtet voellig egal ist, muss man bei einem Concept wissen, was die Anforderungen an den Typ sind. Letzten endes bringt das also rein gar nichts, meiner Meinung nach.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350530</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350530</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Thu, 05 Sep 2013 14:14:37 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 14:32:55 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Waehrend bei einer Funktion die Implementierung von aussen betrachtet voellig egal ist, muss man bei einem Concept wissen, was die Anforderungen an den Typ sind. Letzten endes bringt das also rein gar nichts, meiner Meinung nach.</p>
</blockquote>
<p>Das Argument verstehe ich nicht. Ein Concept erfordert eine bestimmte Schnittstelle, keine bestimmte Implementierung. Du hast bei der Benutzung des Konzepts ebenso eine Abstraktion wie beim Aufruf einer Funktion.</p>
<p>Ob die einzelnen Konzepte wirklich einen Mehrwert bringen, ist dann eine andere Frage.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350537</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 05 Sep 2013 14:32:55 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 16:00:37 GMT]]></title><description><![CDATA[<p>Alles klar, der Talk hat mir sehr geholfen. Fine-Grained COW usw. Das spielt zwar zusammen mit seinen PIMPL-Handles, aber im Prinzip sind das unterschiedliche Konzepte, die eben hier einfach zusammenwirken um möglichst Kosten für Value-Semantics zu zahlen.</p>
<p>Ich finde den PIMPL-Handle-Trick (Oder ihr nennt es Type-Erasure) eigentlich ganz nett, aber wie handhabt man nun, dass der Client-Code bei seinen Objekten eben die Kompatibilität sicherstellen kann?<br />
Mit Basisklassen hilft einem schon die IDE dabei und sagt dass eine Implementierung fehlt, mit dieser Type-Erasure bekommt man wahrscheinlich eine große Menge unleserlicher Fehlermeldungen erst zur Compile-Zeit. Sollte man vielleicht noch auf Concepts warten, um sowas umzusetzen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350551</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Thu, 05 Sep 2013 16:00:37 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 16:01:35 GMT]]></title><description><![CDATA[<p>möglichst WENIG Kosten zu haben/zahlen oder soetwas wollte ich dort oben schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350552</guid><dc:creator><![CDATA[DerEineDaDuWeißtSchon]]></dc:creator><pubDate>Thu, 05 Sep 2013 16:01:35 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Thu, 05 Sep 2013 17:15:33 GMT]]></title><description><![CDATA[<p>DerEineDaDuWeißtSchon schrieb:</p>
<blockquote>
<p>Mit Basisklassen hilft einem schon die IDE dabei und sagt dass eine Implementierung fehlt, mit dieser Type-Erasure bekommt man wahrscheinlich eine große Menge unleserlicher Fehlermeldungen erst zur Compile-Zeit. Sollte man vielleicht noch auf Concepts warten, um sowas umzusetzen?</p>
</blockquote>
<p>Man kann die Existenz von Memberfunktionen zur Compilezeit checken und dann static_asserts durchführen. Mit Concepts wäre das einfacher, aber ein simples<br />
CONCEPT_CHECK(T, std::is_copy_constructible, std::is_nothrow_move_constructible, ...) was dann ein static_assert für jede Bedingung an T ausführt, ist schnell geschrieben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350571</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350571</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Thu, 05 Sep 2013 17:15:33 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Fri, 06 Sep 2013 01:03:00 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Waehrend bei einer Funktion die Implementierung von aussen betrachtet voellig egal ist, muss man bei einem Concept wissen, was die Anforderungen an den Typ sind. Letzten endes bringt das also rein gar nichts, meiner Meinung nach.</p>
</blockquote>
<p>Das Argument verstehe ich nicht. Ein Concept erfordert eine bestimmte Schnittstelle, keine bestimmte Implementierung. Du hast bei der Benutzung des Konzepts ebenso eine Abstraktion wie beim Aufruf einer Funktion.</p>
<p>Ob die einzelnen Konzepte wirklich einen Mehrwert bringen, ist dann eine andere Frage.</p>
</blockquote>
<p>Ein Concept hat keine &quot;Implementierung&quot;, es ist eine Liste an Anforderungen und damit Teil des Interfaces. Bei einer Funktion trifft das nicht zu. Die Funktion ist also eine Abstraktion. Das Concept fuer eine einzige funktion nicht, es ist nur eine Verschiebung des Problems.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350660</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Fri, 06 Sep 2013 01:03:00 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphie Adé on Fri, 06 Sep 2013 05:57:39 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/28420">@Kellerautomat</a>: Ja, das Problem wird verschoben, aber an eine Stelle wo es für den User einfacher ist.</p>
<p>Wenn du eine Funktion aufrufst, kann es sein, dass diese nicht direkt sort aufruft, sondern der Aufruf kann irgendwo tief in einer Kette von Aufrufen verfolgen. In dem Fall ist es gut, wenn du direkt im Interface der Funktion einstellen kannst, dass das übergebene Objekt sortable ist. Insbesondere wenn dann im aufrufstack noch wrappertypen und alles mögliche andere hinzu kommt, kann es für eher unerfahrene Programmierer - und die Welt besteht aus unerfahrenen Programmierern - unmöglich sein, den Fehlermeldungen des Compilers noch sinnvolle Informationen zu entnehmen.</p>
<p>Ich hab selbst erlebt, wie Leute quasi hilflos vor einer Din-A4 Seite langen Fehlermeldung saßen und einfach nicht wussten, wie sie damit umgehen sollen. Ein &quot;Objekt ist nicht sortable&quot; ist dann doch klarer.</p>
<p>---<br />
Und natürlich kann ein freie Funtion als Teil des Interfaces angesehen werden:</p>
<p>begin(container)<br />
end(container)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2350666</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2350666</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Fri, 06 Sep 2013 05:57:39 GMT</pubDate></item></channel></rss>