<?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[Frage zu deletern]]></title><description><![CDATA[<p>Hallo</p>
<p>Wieso werden deleter als Typ und nicht als Funktionszeiger übergeben?</p>
<p>MfG, EOutOfResources</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/284410/frage-zu-deletern</link><generator>RSS for Node</generator><lastBuildDate>Sat, 22 Aug 2026 03:22:36 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/284410.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 31 Mar 2011 17:17:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 17:17:35 GMT]]></title><description><![CDATA[<p>Hallo</p>
<p>Wieso werden deleter als Typ und nicht als Funktionszeiger übergeben?</p>
<p>MfG, EOutOfResources</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042874</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042874</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Thu, 31 Mar 2011 17:17:35 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 17:25:03 GMT]]></title><description><![CDATA[<p>Wo denn? Meinst Du bei std::unique_ptr? Falls ja: Das ist so am flexibelsten. Ähnlich wird es ja auch mit Komperatoren bei set und map gemacht. Du kannst bei dem Ansatz immer noch Funktionszeiger nutzen, wenn Du willst. Man kann sich dann halt nur nicht auf den Defaultkonstruktor verlassen. <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>
<pre><code class="language-cpp">void fun(int*x) {delete x;}

int main() {
  unique_ptr&lt;int,void(*)(int*)&gt; up ( new int, &amp;fun );
  //                                          ^^^^
  // Muss jetzt natürlich explizit angegeben werden, weil
  // D() mit D=void(*)(int*) ein Nullzeiger wird.
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2042883</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042883</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 31 Mar 2011 17:25:03 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 18:31:41 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Meinst Du bei std::unique_ptr? Falls ja: Das ist so am flexibelsten.</p>
</blockquote>
<p>Mit der gleichen Begründung könnte man allerdings auch die Gegenseite vertreten <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>Wenn der Deleter nicht in den Typ einfliesst, muss er nicht bei der Instanziierung des <code>unique_ptr</code> -Templates bekannt sein und kann zur Laufzeit geändert werden (z.B. durch <code>operator=</code> ). Also wie bei <code>shared_ptr</code> . Dafür hat auf diese Weise man weniger Typsicherheit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042924</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042924</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 31 Mar 2011 18:31:41 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:06:58 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Meinst Du bei std::unique_ptr? Falls ja: Das ist so am flexibelsten.</p>
</blockquote>
<p>Mit der gleichen Begründung könnte man allerdings auch die Gegenseite vertreten <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>
</blockquote>
<p>Nein, wieso? Was ist denn an der Beschränkung auf Funtionszeiger so toll? Du erzwingst damit eine Indirektion. Der Deleter-Code kann nicht mehr ge-inline-t werden und sizeof(unique_ptr&lt;T,void(<em>)(T</em>)&gt;) wird dann eher sizeof(void*)+sizeof(void(*)()) sein wohingegen ein zustandsloser Funktor per EBCO (empty base class optimization) auch platztechnisch keinerlei Overhead bedeutet. Wenn Du Dich auf Funktionszeiger beschränkst, erzwingst Du Overhead, den Du nicht immer gebrauchen kannst. Auch gestaltet sich die Konvertierung von Zeigern (derived -&gt; base) als wenigstens &quot;schwierig&quot; bei Funktionszeiger-Deletern, wohingegen unique_ptr mit dem Defaultdeleter in der Hinsicht keine Probleme macht.</p>
<p>Ich verstehe absolut nicht, was Du gegen das unique_ptr-Design hast. Dadurch, dass der Deleter-Typ ein Templateparameter ist, kannst Du doch weiterhin Funktionszeiger benutzen, wenn Du willst. Und wenn nicht, dann eben einen anderen Funktortypen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042933</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042933</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:06:58 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:18:03 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>und kann zur Laufzeit geändert werden</p>
</blockquote>
<p>Dir ist klar, dass auch Klassen einen Funktionszeiger speichern (und ändern) können und die Lösung von Klassen eine Übermenge zu der Zeigerlösung ist?</p>
<p>Vielleicht spart sie sich in wenigen Ausnahmefällen etwas Schreibarbeit, aber noch viel mehr Fälle sind quasi unmöglich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042939</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042939</guid><dc:creator><![CDATA[suck senn]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:18:03 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:29:12 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>Wieso werden deleter als Typ und nicht als Funktionszeiger übergeben?</p>
</blockquote>
<p>Abgesehen von genannten Gründen, würde mich das stark limitieren, da ich auch keine Objekte mehr übergeben könnte. Zum Beispiel:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
struct deleter {
    void operator() (T* p) {
        delete p;
    } 
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2042943</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042943</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:29:12 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:36:43 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Nein, wieso? Was ist denn an der Beschränkung auf Funtionszeiger so toll?</p>
</blockquote>
<p>Nichts, aber die hat man ja auch nicht. <code>boost::shared_ptr</code> kann beliebige Funktionsobjekte als Deleter nehmen.</p>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Du erzwingst damit eine Indirektion.</p>
</blockquote>
<p>Welche weniger performant, aber flexibler ist. Die Indirektion ist einerseits Compiler-Firewall, andererseits erlaubt sie ein Austauschen zur Laufzeit und die Interaktion von Smart-Pointern mit verschiedenen Deletern. Ausserdem ist der Code normalerweise kürzer, als wenn man gleiches mit statischen Template-Parametern erreichen will.</p>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Ich verstehe absolut nicht, was Du gegen das unique_ptr-Design hast.</p>
</blockquote>
<p>Gegen das Design habe ich nichts, im Gegenteil. Für einen allgemeingültigen RAII-Pointer macht <code>unique_ptr</code> seine Sache sehr gut. Aber für spezielle Anliegen soll er sich auch eingestehen, dass andere Smart-Pointer-Typen besser geeignet sind. <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/2042951</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042951</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:36:43 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:44:30 GMT]]></title><description><![CDATA[<p>Etwas ausführlicher:</p>
<p>Ich halte zu viel Generizität für ein Problem. Andrei Alexandrescu zeigt das mit seinem <code>SmartPtr</code> -Template noch viel extremer auf. Schlussendlich kann man zwar alles irgendwie hinbiegen, doch man hat ein Biest, das verschiedenste Semantiken vereint. Beim Versuch, selbst Erweiterungen zu schreiben, merkt man auch relativ schnell, dass das Ganze doch nicht so flexibel ist und man schnell an Grenzen stösst. Gewisse Konzepte lassen sich schlecht eingliedern, oder führen zu massiv Boilerplate-Code. Das hat mich auch veranlasst, einige Smart-Pointer mit klarer, spezialisierter Semantik selbst zu implementieren, was sich sehr positiv auf deren Anwendung auswirkt.</p>
<p>Interessanterweise ist so ein Design im Bezug auf objektorientierte Programmierung als Anti-Pattern verpönt (Gott-Klasse), aber bei Templates stört es niemanden. Weil halt die einzelnen Teile weniger gekoppelt sind und man keinen Overhead durch zusätzliche Funktionalität hat. Die übliche &quot;Du musst ja nicht alles verwenden&quot;-Philosophie. Aber betrachtet man Alexandrescus <code>SmartPtr</code> mit all seinen Policies als zusammengehörige Funktionalität, kann die Komplexität durchaus unvorteilhaft sein.</p>
<p>Zurück zum Thema: Nur weil <code>unique_ptr</code> im Prinzip sehr vieles <em>könnte</em>, muss man ihn dafür nicht auch <em>einsetzen</em>. Alternativen sind manchmal die bessere Wahl.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042957</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042957</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:44:30 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 19:50:41 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Du erzwingst damit eine Indirektion.</p>
</blockquote>
<p>Welche weniger performant, aber flexibler ist. Die Indirektion ist einerseits Compiler-Firewall,</p>
</blockquote>
<p>Das ist doch Quark. Du willst mir sagen, dass eine Beschränkung auf Funktionszeiger flexibler sei, als das Ersetzen des Funktionszeigertypen durch einen Templateparameter, der immer noch ein Funktionszeigertyp sein kann.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>andererseits erlaubt sie ein Austauschen zur Laufzeit und die Interaktion von Smart-Pointern mit verschiedenen Deletern. Ausserdem ist der Code normalerweise kürzer, als wenn man gleiches mit statischen Template-Parametern erreichen will.</p>
</blockquote>
<pre><code class="language-cpp">template&lt;class T&gt;
using nexus_ptr = std::unique_ptr&lt;T,void(*)(T*)&gt;;
</code></pre>
<p>Gut, unique_ptr lässt sich den Deleter nicht nachträglich manipulieren. Das hat aber nichts damit zu tun, dass dafür ein Template-Typparameter verwendet wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042961</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042961</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 31 Mar 2011 19:50:41 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Thu, 31 Mar 2011 20:31:35 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Das ist doch Quark. Du willst mir sagen, dass eine Beschränkung auf Funktionszeiger flexibler sei</p>
</blockquote>
<p>Nein. Du hast mit der &quot;Beschränkung auf Funktionszeiger&quot; angefangen, obwohl ich dies gar nie erwähnt habe. Wovon ich sprach, ist Type Erasure wie beim Deleter von <code>boost::shared_ptr</code> . Okay, &quot;flexibler&quot; ist ein zweischneidiges Schwert. Man kann damit zwar insgesamt weniger machen, weil man mit dem statischen Ansatz die Type Erasure nachbauen kann. Aber der Nachbau wird um einiges komplizierter als das Original, bei dem die von mir angesprochene Flexibilität direkt genutzt werden kann.</p>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Gut, unique_ptr lässt sich den Deleter nicht nachträglich manipulieren. Das hat aber nichts damit zu tun, dass dafür ein Template-Typparameter verwendet wird.</p>
</blockquote>
<p>Es hat aber damit zu tun, dass der Deleter-Typ fest in den Smart-Pointer-Typ eingeprägt ist. Mit dynamischer Polymorphie bist du in dieser Hinsicht flexibler. Mir ist übrigens klar, dass du über eine Indirektion etwas sehr Ähnliches auch mit <code>unique_ptr</code> erreichen kannst. Wir hatten die Diskussion <a href="http://www.c-plusplus.net/forum/281728-20?highlight=uniqueptr" rel="nofollow">schon einmal</a>, damals konntest du mit mit Mühe und Not etwas basteln, das zwar nahe an meinen spezialisierten Smart-Pointer kam, aber eben nicht ganz :p</p>
<p>Und sobald man sich eine andere Besitzsemantik einrichten will, nützt einem <code>unique_ptr</code> auch nichts mehr. Nur mit <code>unique_ptr</code> und <code>shared_ptr</code> hat man noch nicht alle Fälle abgedeckt. Jedoch recht viele.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2042978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2042978</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 31 Mar 2011 20:31:35 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Fri, 01 Apr 2011 11:39:10 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Nur mit <code>unique_ptr</code> und <code>shared_ptr</code> hat man noch nicht alle Fälle abgedeckt. Jedoch recht viele.</p>
</blockquote>
<p>...behaupte ich auch nicht. Es ist ja nicht mal geklärt, um was für Deleter es sich in diesem Thread handelt. Ich hatte mit unique_ptr ja nur geraten. Du sagtest dazu folgendes:</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Meinst Du bei std::unique_ptr? Falls ja: Das ist so am flexibelsten.</p>
</blockquote>
<p>Mit der gleichen Begründung könnte man allerdings auch die Gegenseite vertreten <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>
</blockquote>
<p>Das sieht für mich immer noch nach der Behauptung aus, dass</p>
<pre><code class="language-cpp">template&lt;class T&gt;
class unique_ptr {
  T* ptr;
  void (*del)(T*);
public:
  explicit unique_ptr(T*);
  explicit unique_ptr(T*,void(*)(T*));
  ...
};
</code></pre>
<p>flexibler sei als</p>
<pre><code class="language-cpp">template&lt;class T, class D = default_deleter&lt;T&gt; &gt;
class unique_ptr {
  tuple&lt;T*,D&gt; data;
public:
  explicit unique_ptr(T*, D = D());
  ...
};
</code></pre>
<p>Mag sein, dass Du es anders gemeint hast. Aber so habe ich Deinen Kommentar verstanden. Und natürlich stimmt das so nicht, da Du immernoch für D void(<em>)(T</em>) einsetzen kannst.</p>
<p>kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2043179</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2043179</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 01 Apr 2011 11:39:10 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Fri, 01 Apr 2011 13:38:18 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Wenn der Deleter nicht in den Typ einfliesst, muss er nicht bei der Instanziierung des <code>unique_ptr</code> -Templates bekannt sein und kann zur Laufzeit geändert werden (z.B. durch <code>operator=</code> ). Also wie bei <code>shared_ptr</code> . Dafür hat auf diese Weise man weniger Typsicherheit.</p>
</blockquote>
<p>Der Grund den Deleter-Typ mit in den unique_ptr reinzuknoten ist einfach damit unique_ptr so effizient wie möglich bleibt.<br />
Type-Erasure würde hier erfordern dass wie bei shared_ptr ein Hilfsobjekt dynamisch angelegt werden muss.<br />
shared_ptr braucht das sowieso, also ist es da egal. unique_ptr braucht es nicht, also auch keine Type-Erasure für den deleter.</p>
<p>ps:<br />
wenn dann bräuchte man IMO mindestens <code>void(*)(T*, void*)</code> .<br />
Damit könnte man so ziemlich alles abdecken, bräuchte aber trotzdem keinen zusätzlichen Template-Parameter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2043241</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2043241</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 01 Apr 2011 13:38:18 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu deletern on Fri, 01 Apr 2011 14:11:58 GMT]]></title><description><![CDATA[<p>Ja, wie angedeutet war &quot;flexibler&quot; vielleicht etwas ungünstig formuliert, da man mit dem momentanen Design auch Type Erasure weitgehend nachbauen kann.</p>
<p>Das Problem ist aber, dass der Aufwand für diesen Nachbau relativ hoch ist und für eine vernünftige Anwendung auch eher fortgeschrittene Kenntnisse (teilweise aus C++0x) erfordert. Daher denke ich, bei der Notwendigkeit einer dynamischeren Technik wird der durchschnittliche Programmierer diese Möglichkeit nicht nutzen, sondern eher zu <code>shared_ptr</code> greifen, wo die Deleter mit dynamischer Polymorphie bereits fertig implementiert sind.</p>
<p>Natürlich hat der <code>unique_ptr</code> mit seinem momentanen Design viele Vorteile, da man grundsätzlich mehr damit machen kann und keine Performance verliert. Wie schon mehrfach erwähnt bin ich damit zufrieden. Aber man sollte auch sehen, dass das momentane Design grösstenteils auf die naheliegendste Art benutzt werden wird (über einen Funktor als Deleter), während speziellere Anforderungen mit anderen Smart-Pointer-Typen massiv einfacher gelöst werden können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2043264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2043264</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 01 Apr 2011 14:11:58 GMT</pubDate></item></channel></rss>