<?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[list, erase]]></title><description><![CDATA[<p>hallo...</p>
<p>ich habe eine liste geschrieben(für die uni, sonst hätt ich schon <code>std::list</code> genommen ^^) und habe jetzt ein Problem mit dem erase...<br />
Die Signatur hat ja so auszusehen:</p>
<p><code>iterator erase(const_iterator where)</code></p>
<p>aber wie würdet ihr aus dem const_iterator dann nen iterator machen?<br />
Mein const_iterator sieht so in etwa aus:</p>
<pre><code class="language-cpp">struct const_iterator : /*typedefs, operatoren, ...*/
{
public:
 //operatoren, copyctor, ...
private:
  const node *data;

  const_iterator(const node *_data) : data(_data) {}
//meine liste ist als friend eingetragen, weil dieser ctor ja nicht von außen aufgerufen werden sollte...
};
</code></pre>
<p>Iterator ist analog dazu - nur eben ohne die beiden <code>const</code> `s</p>
<p>Mein erase würde ich so in etwa schreiben:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
typename list&lt;T&gt;::iterator list&lt;T&gt;::erase(const_iterator to_delete)
{
  const iterator after( static_cast&lt;node*&gt;(to_delete.data-&gt;next) );
  _erase(to_delete.data, to_delete.data-&gt;prev, after);
  return after;
}
</code></pre>
<p>Der static_cast ist nötig, da ich auch 2 dummy-nodes habe (anfang und ende) und deshalb immererst von dem dummy-node zum richtigen node casten muss...</p>
<p>edit (hatte das prob ganz vergessen zu schildern): das problem hier ist natürlich, dass ich noch nen const_cast einbauen müsste - aber iwann wirds ja auch mal hässlich... und ich dachte, dass es vll ne bessere möglichkeit geben würde ^^</p>
<p>Mein const_iterator hat auch nen ctor für iteratoren - aber umgedreht find ich es ein wenig komisch.. Ich hab auch mal bissl in der MSVC-Standard-Lib gesucht - soweit ich das dort gesehen habe, hat dort der const_iterator aber kein <code>const node</code> -Pointer sondern einen &quot;normalen&quot; node-Pointer - wie eben der normale Iterator auch... Würdet ihr das auch so machen? Oder wie sähe eure Lösung aus?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/242425/list-erase</link><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 00:24:23 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/242425.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 03 Jun 2009 15:53:12 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to list, erase on Wed, 03 Jun 2009 15:54:40 GMT]]></title><description><![CDATA[<p>hallo...</p>
<p>ich habe eine liste geschrieben(für die uni, sonst hätt ich schon <code>std::list</code> genommen ^^) und habe jetzt ein Problem mit dem erase...<br />
Die Signatur hat ja so auszusehen:</p>
<p><code>iterator erase(const_iterator where)</code></p>
<p>aber wie würdet ihr aus dem const_iterator dann nen iterator machen?<br />
Mein const_iterator sieht so in etwa aus:</p>
<pre><code class="language-cpp">struct const_iterator : /*typedefs, operatoren, ...*/
{
public:
 //operatoren, copyctor, ...
private:
  const node *data;

  const_iterator(const node *_data) : data(_data) {}
//meine liste ist als friend eingetragen, weil dieser ctor ja nicht von außen aufgerufen werden sollte...
};
</code></pre>
<p>Iterator ist analog dazu - nur eben ohne die beiden <code>const</code> `s</p>
<p>Mein erase würde ich so in etwa schreiben:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
typename list&lt;T&gt;::iterator list&lt;T&gt;::erase(const_iterator to_delete)
{
  const iterator after( static_cast&lt;node*&gt;(to_delete.data-&gt;next) );
  _erase(to_delete.data, to_delete.data-&gt;prev, after);
  return after;
}
</code></pre>
<p>Der static_cast ist nötig, da ich auch 2 dummy-nodes habe (anfang und ende) und deshalb immererst von dem dummy-node zum richtigen node casten muss...</p>
<p>edit (hatte das prob ganz vergessen zu schildern): das problem hier ist natürlich, dass ich noch nen const_cast einbauen müsste - aber iwann wirds ja auch mal hässlich... und ich dachte, dass es vll ne bessere möglichkeit geben würde ^^</p>
<p>Mein const_iterator hat auch nen ctor für iteratoren - aber umgedreht find ich es ein wenig komisch.. Ich hab auch mal bissl in der MSVC-Standard-Lib gesucht - soweit ich das dort gesehen habe, hat dort der const_iterator aber kein <code>const node</code> -Pointer sondern einen &quot;normalen&quot; node-Pointer - wie eben der normale Iterator auch... Würdet ihr das auch so machen? Oder wie sähe eure Lösung aus?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1720528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1720528</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 03 Jun 2009 15:54:40 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Wed, 03 Jun 2009 16:30:17 GMT]]></title><description><![CDATA[<p>1. Nach bisherigem Standard erwartet <code>std::list::erase</code> ein <code>iterator</code> :<br />
<a href="http://www.cplusplus.com/reference/stl/list/erase/" rel="nofollow">http://www.cplusplus.com/reference/stl/list/erase/</a></p>
<p>2. Derzeit sieht es so aus, dass im nächsten Standard dies abgeändert und ein <code>const_iterator</code> erwartet wird.</p>
<p>3. Die Implementierung der Std-Lib des MSVC erwartet heute schon ein <code>const_iterator</code> .</p>
<p>4. In der Std-Lib zum MSVC hat man es sich einfach gemacht und den <code>iterator</code> von <code>const_iterator</code> abgeleitet. Der MSVC setzt hier also bewusst auf Slicing.</p>
<p>5. Ich würde bereits nach dem neuen Standard gehen und ein <code>const_iterator</code> erwarten und wohl auch so ähnlich lösen, wie es in der Std-Lib des MSVC gelöst ist. Obwohl die Frage durchaus ein wenig berechtigt ist, ob ein <code>iterator</code> wirklich auch ein <code>const_iterator</code> ist (is-a Beziehung).</p>
<p>6. Zwei alternativen wären wohl:<br />
- Die Verbindung von den beiden Iteratoren über <code>friend</code> und dann in <code>const_iterator</code> einen Konstruktor zur Verfügung stellen, welcher einen <code>iterator</code> erwartet. Vom <code>iterator</code> wird dann der Zeiger auf den Node geholt.<br />
- Den <code>const_iterator</code> so zu entwerfen, dass er nur als Wrapper um einen <code>iterator</code> dient. Ähnlich wie der Wrapper für <code>reverse_iterator</code> .</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1720552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1720552</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 03 Jun 2009 16:30:17 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Wed, 03 Jun 2009 19:30:32 GMT]]></title><description><![CDATA[<p>Du würdest also insbesondere const_iterator keinen const-Pointer sondern einen normalen(mutable) Pointer halten lassen?!</p>
<p>Oder würdest du im CTor von iterator, der const_iterator erwartet, dann einfach nen const_cast machen? (darf man das dort dann überhaupt, ohne darüber nachdenken zu müssen? ich denk ja schon, aber sicher bin ich mir im Moment nicht ^^)</p>
<p>Das mit dem mutable Pointer gefällt mir nicht so recht, weil man imho bei jeder const-methode, die einen iterator wiedergibt erst das const wegcasten müsste?! (z.bsp. <code>begin()</code> und <code>end()</code> )</p>
<p>und dann hab ich mit diesem konzept an sich ein problem:<br />
ich habe eine klasse, die eine liste oder was auch immer als member hat - und ich gebe dem anwender eine funktion, die ihm nen <code>const_iterator</code> zurückgibt - aber jz kann er diesen <code>const_iterator</code> eben doch in nen <code>iterator</code> umwandeln -.- Man kann dem User also nicht mehr eindeutig zeigen, dass er seine Griffeln von dem Container lassen soll... So denkt er sich bestimmt: <code>const_iterator</code> : ich darf also alles machen, was ich damit machen kann - also kann ich auch das Objekt löschen und hab außerdem dann auch gleich noch nen <code>iterator</code> des nächsten Elements...</p>
<p>Spätestens, wenn bis-jetzt-Member-Funktionen der Container als freie Funktionen implementiert werden - wie dies ja im nächsten Standard passieren sollte, oder hab ich mir da was falsch gemerkt?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1720652</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1720652</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 03 Jun 2009 19:30:32 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Wed, 03 Jun 2009 20:17:47 GMT]]></title><description><![CDATA[<p>Weder <code>mutable</code> noch <code>const_cast</code> sind mit allen drei Lösungen nötig.</p>
<p>1. Ein <code>const_iterator</code> ist nicht konstant, sondern worauf er verweist ist konstant. Du kannst allerdings einen normalen Zeiger oder sowas nehmen, also einen Zeiger auf ein nicht konstantes Objekt, und die konstante Eigenschaft einfach durch die Funktionen/Rückgabewerte hervorrufen.</p>
<p>2. Ich sagte ein <code>const_iterator</code> hat einen Konstruktor, welcher einen <code>iterator</code> aufnimmt. Somit würde ein Zeiger auf ein nicht konstantes Objekt and einen Zeiger auf ein konstantes Objekt übergeben werden, absolut kein Problem.</p>
<p>3. Nicht der Iterator sagt was im Container passiert, sondern der Container sagt es. Der Iterator hat nur die Kontrolle über das Element. Allerdings, wie ich schon im Punkt 1 gesagt habe, soll nicht die Konvertierung von einem <code>const_iterator</code> in einen <code>iterator</code> möglich sein, sondern genau der umgedrehte Fall.</p>
<p>4. Lies alles nochmals genau durch. Ich habe ein wenig das Gefühl, dass du ein paar Dinge durcheinander bringst. Was ist genau const, wer hat die Kontrolle, in welche Richtungen kann man konvertieren? Notfalls macht dir eine Skizze <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1720678</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1720678</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 03 Jun 2009 20:17:47 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 10:38:32 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Weder mutable noch const_cast sind mit allen drei Lösungen nötig.</p>
</blockquote>
<p>ich meinte mutable im Gegensatz zu const und nicht das keyword ^^</p>
<p>Ich glaube, wir haben ein wenig aneinander vorbeigeredet - die konvertierung von <code>iterator</code> in <code>const_iterator</code> ist mir klar und die besteht auch jetzt schon... (womit 1.+2. sich erledigt hätten ^^)<br />
allerdings hatte ich ein prob, aus dem const_iterator, den erase bekommt nen normalen iterator zu machen - aber das löse ich wohl jz auch, indem ich kein <code>const node</code> pointer sondern nen non-const pointer speicher...<br />
allerdings wird es dann ja schon wieder doof, die begin() und end() funktionen zu implementieren!?</p>
<pre><code class="language-cpp">iterator begin()
{
  return iterator( static_cast&lt;node*&gt; (m.anchor_begin.next) );
}

const_iterator begin() const
{
  return const_iterator( static_cast&lt;node*&gt; (m.anchor_begin.next) );
  //erwartet nen node*, bekommt aber nen const node*, da const-fkt...
}
</code></pre>
<p>die const-methode würde jetzt noch einen zusätzlichen const-cast benötigen, da const_iterator ja kein const-node pointer mehr erwartet, weil er nur noch nen non-const pointer speichert?!<br />
Wie du um den rumkommen möchtest, ist mir noch immer unklar...</p>
<p>zu 3. nochmal:<br />
aber mit erase hat man ja dann im endeffekt die umwandlung von einem <code>const_iterator</code> in einen (anderen) <code>iterator</code> ...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1720915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1720915</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 10:38:32 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 12:21:44 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>Ich glaube, wir haben ein wenig aneinander vorbeigeredet - die konvertierung von <code>iterator</code> in <code>const_iterator</code> ist mir klar und die besteht auch jetzt schon... (womit 1.+2. sich erledigt hätten ^^)</p>
</blockquote>
<p>Nicht wirklich, dieser Satz betrifft nur Punkt 2.</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>allerdings hatte ich ein prob, aus dem const_iterator, den erase bekommt nen normalen iterator zu machen - aber das löse ich wohl jz auch, indem ich kein <code>const node</code> pointer sondern nen non-const pointer speicher...</p>
</blockquote>
<p>Das hier dagegen betrifft Punkt 1. <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>unskilled schrieb:</p>
<blockquote>
<p>allerdings wird es dann ja schon wieder doof, die begin() und end() funktionen zu implementieren!?</p>
</blockquote>
<p>Ehm, nö.</p>
<pre><code class="language-cpp">class TestClass
{
private:
  int* m_intPtr;

  // ...

public:
  int* get_int_ptr() const
  {
    // Hier ist m_intPtr vom Typ: int* const
    // Der Zeiger ist konstant nicht das Objekt, worauf er zeigt.

    // Das folgende geht also ohne Probleme:
    return m_intPtr;
  }
}
</code></pre>
<p>unskilled schrieb:</p>
<blockquote>
<p>zu 3. nochmal:<br />
aber mit erase hat man ja dann im endeffekt die umwandlung von einem <code>const_iterator</code> in einen (anderen) <code>iterator</code> ...</p>
</blockquote>
<p>Du meinst hier wohl über den Rückgabewert, oder?<br />
Das spielt jedenfalls keine Rolle. Ein Iterator ist nur ein Verweis auf ein Objekt. Wenn du den Iterator an <code>erase</code> übergibst, ist das Objekt sowieso weg. Was du zurückbekommst, ist ein Iterator auf das nächste Objekt. Dieser Iterator ist natürlich kein konstanter Verweis, denn wenn du ein <code>erase</code> auf einen Container aufrufen kannst, dann hast du einen nicht-konstanten Container. Man darf also die Elemente des Containers modifizieren.</p>
<p>Ganz davon abgesehen, da du den nicht-konstanten Container hast, könntest du sogar den Wert, auf welcher dein <code>const_iterator</code> verweist, ändern gehen. Einmal <code>std::distance</code> , und dann einen normalen <code>iterator</code> holen und einmal <code>std::advance</code> .</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721012</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721012</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 04 Jun 2009 12:21:44 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 13:00:39 GMT]]></title><description><![CDATA[<p>Aber folgendes geht leider nicht:</p>
<pre><code class="language-cpp">struct TestClass
{
	struct base
	{
		base *next;
		base *prev;
	};

	struct node : base
	{
		int data;
	};

	struct _m
	{
		base a;
	} m;

	node* get() const
	{
		return static_cast&lt;node*&gt; (&amp;m.a);
//		return const_cast &lt;node*&gt; ( static_cast&lt;const node*&gt; (&amp;m.a) );
	} 
};

int main()
{
	TestClass tmp;
	TestClass::node* x = tmp.get();
}
</code></pre>
<p>erzeugt</p>
<p>MSVC schrieb:</p>
<blockquote>
<p>error C2440: 'static_cast' : cannot convert from 'const TestClass::base *' to 'TestClass::node *'</p>
</blockquote>
<p>das meinte ich mit const_cast - oder mach ich da was falsch?!<br />
es liegt offensichtlich daran, dass ich die member an sich in dem struct gekapselt habe... brauch ich aber, weil ich 2 dummy-knoten habe und die nach jedem ctor aufeinander zeigen sollen - also hab ich _m einfach nen standard-ctor gegeben und ruf den in jedem ctor auf (was zwar eigtl gar nicht nötig ist, aber ich habs trotzdem mal gemacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> )...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721055</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 13:00:39 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 13:13:43 GMT]]></title><description><![CDATA[<p>Du könntest den Dummyknoten dynamisch erzeugen oder verpass dem Dummyknoten Objekt das Keyword <code>mutable</code> .</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721061</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721061</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 04 Jun 2009 13:13:43 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 13:32:29 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Du könntest den Dummyknoten dynamisch erzeugen...</p>
</blockquote>
<p>und somit wäre der standard-ctor nich mehr exception-safe...<br />
außerdem find ich es unnötig...</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>oder verpass dem Dummyknoten Objekt das Keyword <code>mutable</code> .</p>
</blockquote>
<p>hab ich auch schon dran gedacht, erschien mir aber irgendwie so unelegant...<br />
du würdest wohl <code>mutable</code> nutzen?!</p>
<p>bb</p>
<p>edit: oder würdest du den const_cast lassen? eigtl taucht der im kompilierten programm ja so und so nicht mehr auf, oder? außerdem sollte da ja auch nichts schief gehen können, oder? ^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721064</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721064</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 13:32:29 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 13:33:10 GMT]]></title><description><![CDATA[<p>Ob ich den Dummyknoten dynamisch oder per <code>mutable</code> anlegen würde, ist schwer zu sagen. Ich tendiere allerdings zu dynamisch.</p>
<p>Es gibt von mir aus gesehen ein Killerargument gegen die <code>mutable</code> Lösung:</p>
<pre><code class="language-cpp">int main()
{
  yourlib::list&lt;MassiveObject&gt; list;

  return 0;
}
</code></pre>
<p>Wenn <code>MassiveObject</code> wirklich ein zu grosses Objekt ist, dann hast du hier plötzlich einen Stackoverflow. Es ist zwar ein eher theoretisches Problem, aber ich sehe zu wenig Vorteile bei der <code>mutable</code> Lösung, welche mich dazu bringen würden, das Risiko dieses theoretischen Problems einzugehen.</p>
<p>Zur Exceptionsicherheit:<br />
Wieso sollte der Konstruktor nicht mehr exceptionsicher sein? Wenn man die Sache richtig umsetzt, dann ist das doch ohne Probleme möglich. Wo siehst du hier ein Problem?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721070</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721070</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 04 Jun 2009 13:33:10 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 13:44:26 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>[...] Stackoverflow [...]</p>
</blockquote>
<p>Die Dummy-Knoten beinhalten aber keine Daten - nur einen Zeiger auf next und prev... so könnte es auch keinen Stackoverflow geben, oder seh ich das falsch?</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Wieso sollte der Konstruktor nicht mehr exceptionsicher sein?</p>
</blockquote>
<p>weil ich dann 2 <code>new</code> s hätte?!</p>
<p>bis jetzt sieht der Standard-CTor so aus:<br />
<code>_m() : anchor_begin(&amp;anchor_end, nullptr), anchor_end(nullptr, &amp;anchor_begin) {}</code></p>
<p>danach würde er dann nicht nur nicht mehr so schön gehen sondern zusätzlich dazu könnte an 2 Stellen eine exception fliegen...</p>
<pre><code class="language-cpp">_m() : anchor_begin(nullptr), anchor_end(new base_node)
{
  anchor_begin = new base_node(anchor_end, nullptr);
  anchor_end-&gt;prev = anchor_begin;
  anchor_end-&gt;next = nullptr;
}
</code></pre>
<p>die nullptr sind zwar nicht notwendig und ich könnte einfach den random-wert drin stehen lassen, aber darin sehe ich keinen vorteil...<br />
und der ctor ist so noch nicht mal exception-safe...</p>
<p>wenn ich so drüber nachdenke, denke ich fast, dass ich die lösung mit dem const_cast lasse - da er (imho) genau 0takte kostet und niemals konstante daten geändert werden. Somit sollte es auch nicht undefiniertes verhalten liefern können - selbst, wenn der compiler konstante daten in irgend nen read-only speicher schreiben sollte... Richtig?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721083</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721083</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 13:44:26 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 14:00:04 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>Die Dummy-Knoten beinhalten aber keine Daten - nur einen Zeiger auf next und prev... so könnte es auch keinen Stackoverflow geben, oder seh ich das falsch?</p>
</blockquote>
<p>Ah, sorry, da habe ich nicht genug weit mitgedacht. Habe selber noch nie eine Liste mit Dummyknoten implementiert <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="😉"
    /><br />
Die paar zusätzlichen ifs, welche dann nötig sind, waren mir bisher immer 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>
<p>Dann sieht aber <code>mutable</code> durchaus lecker aus <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>unskilled schrieb:</p>
<blockquote>
<p>weil ich dann 2 <code>new</code> s hätte?!</p>
</blockquote>
<p>Ja und? Man könnte zum Beispiel einen <code>scoped_ptr</code> nehmen, wäre sowieso nicht so verkehrt. Nur weil man zwei news hat, heisst das doch nicht, dass man den Konstruktor nicht Exception sicher machen kann.</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>bis jetzt sieht der Standard-CTor so aus:<br />
<code>_m() : anchor_begin(&amp;anchor_end, nullptr), anchor_end(nullptr, &amp;anchor_begin) {}</code></p>
</blockquote>
<p>Geht sowas überhaupt laut Standard? Da bin ich mir jetzt gar nicht so sicher. Es sollte doch eine Reihenfolge zu beachten sein. Zumindest dürfte es hier eine Warnung geben, ähnlich wie wenn man <code>this</code> in der Intialisierungsliste verwendet.</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>wenn ich so drüber nachdenke, denke ich fast, dass ich die lösung mit dem const_cast lasse - da er (imho) genau 0takte kostet und niemals konstante daten geändert werden. Somit sollte es auch nicht undefiniertes verhalten liefern können - selbst, wenn der compiler konstante daten in irgend nen read-only speicher schreiben sollte... Richtig?</p>
</blockquote>
<p>Sofern du dir da ganz sicher bist, dass niemand anderes oder auch du &quot;ausversehen&quot; das Objekt doch verändert, weil du oder der andere sich nicht daran erinnert, dass der Zeiger auf ein nicht konstantes Objekt eigentlich ein Zeiger auf ein konstantes Objekt ist.</p>
<p>Ich mag <code>const_cast</code> nicht, da würde ich eher <code>mutable</code> nehmen, da es das Design sicherer macht.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721091</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721091</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 04 Jun 2009 14:00:04 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 14:14:43 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>unskilled schrieb:</p>
<blockquote>
<p>bis jetzt sieht der Standard-CTor so aus:<br />
<code>_m() : anchor_begin(&amp;anchor_end, nullptr), anchor_end(nullptr, &amp;anchor_begin) {}</code></p>
</blockquote>
<p>Geht sowas überhaupt laut Standard? Da bin ich mir jetzt gar nicht so sicher. Es sollte doch eine Reihenfolge zu beachten sein. Zumindest dürfte es hier eine Warnung geben, ähnlich wie wenn man <code>this</code> in der Intialisierungsliste verwendet.</p>
</blockquote>
<p>Nö - die Adresse steht ja schon fest - und was anderes verwende ich ja nicht... kommt auch keine Warnung...</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>unskilled schrieb:</p>
<blockquote>
<p>wenn ich so drüber nachdenke, denke ich fast, dass ich die lösung mit dem const_cast lasse - da er (imho) genau 0takte kostet und niemals konstante daten geändert werden. Somit sollte es auch nicht undefiniertes verhalten liefern können - selbst, wenn der compiler konstante daten in irgend nen read-only speicher schreiben sollte... Richtig?</p>
</blockquote>
<p>Sofern du dir da ganz sicher bist, dass niemand anderes oder auch du &quot;ausversehen&quot; das Objekt doch verändert, weil du oder der andere sich nicht daran erinnert, dass der Zeiger auf ein nicht konstantes Objekt eigentlich ein Zeiger auf ein konstantes Objekt ist.</p>
</blockquote>
<p>Ja, ich bin mir sicher, dass niemand was verändert... wenn das Objekt an sich const ist, dann wird bei begin() und end() ein const_iterator erzeugt und man kann nur über advance oder so nen iterator draus machen - aber das ist ja immer so ^^ ansonsten hat man keine möglichkeiten, das objekt zu ändern...</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Ich mag <code>const_cast</code> nicht, da würde ich eher <code>mutable</code> nehmen, da es das Design sicherer macht.</p>
</blockquote>
<p>Hmm... mutable sieht immer so hässlich aus : D<br />
Da nehm ich lieber irgendwo nen const_cast, den so und so niemand sieht <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=";D"
      alt="😉"
    /></p>
<p>bb</p>
<p>Danke für deine Hilfe und Geduld <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721111</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721111</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 14:14:43 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 14:27:19 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p>Nö - die Adresse steht ja schon fest - und was anderes verwende ich ja nicht... kommt auch keine Warnung...</p>
</blockquote>
<p>Problem wäre aber sowas:</p>
<pre><code class="language-cpp">class Inner
{
  int x;

public:
  Inner(Inner* other)
    : x(0)
  {
    other-&gt;x = 4;
  }
}

class Outer
{
  Inner a, b;

public:
  Outer()
    : a(&amp;b) // Hier würde dem x in b 4 zugewiesen werden,
            // Obwohl das Objekt gar noch nicht konstruiert ist.
    , b(&amp;a)
  {
  }
}
</code></pre>
<p>Klar, bei dir ist das nicht der Fall, weil du nur den Zeiger abspeicherst, aber deswegen dachte ich, dass zumindest eine Warnung kommen würde, denn der Kompiler wird sicher nicht genau nachprüfen, was mit dem Zeiger passiert. Er könnte es zum Teil sogar gar nicht.</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>Hmm... mutable sieht immer so hässlich aus : D<br />
Da nehm ich lieber irgendwo nen const_cast, den so und so niemand sieht <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=";D"
      alt="😉"
    /></p>
</blockquote>
<p>Naja, ist deine Entscheidung ...</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721119</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721119</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 04 Jun 2009 14:27:19 GMT</pubDate></item><item><title><![CDATA[Reply to list, erase on Thu, 04 Jun 2009 14:34:06 GMT]]></title><description><![CDATA[<p>jopp - aber auch bei deinem bsp bekomm ich mit dem msvc auf w4 keine warning...<br />
warnt gcc bei sowas?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1721127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1721127</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 04 Jun 2009 14:34:06 GMT</pubDate></item></channel></rss>