<?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[Zwei Design Fragen bei Operatorüberladung]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Ich habe mal wieder zwei Designfragen.</p>
<p>1. Frage:<br />
Ich habe mich nun ernsthaft mal mit den Boost.Operators beschäftigt, nachdem pumuckl die Artikel geschrieben hat. Dabei habe ich mir zum Beispiel ein Hilfsmittel für Iteratoren geschrieben, welche auf einen Zeiger verweisen. Bevor jemand mit Boost.PtrContainer kommt, es geht nicht darum, dass der Container die Zeiger auch besitzt <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 />
Dabei enstand folgende Klasse mit Basisklassen. Ist sowas überhaupt noch lesbar? Ich habe es programmiert, ich kann es lesen, aber ob es andere können, würde mich in diesem Fall schon ein wenig interessieren. Natürlich bevorzugt Leute, welche sich mit Boost.Operators auskennen.</p>
<pre><code class="language-cpp">template&lt;typename IterT&gt;
class PtrIterator
	: public std::iterator&lt;
		std::random_access_iterator_tag,
		typename boost::remove_pointer&lt;
			typename std::iterator_traits&lt;IterT&gt;::value_type
		&gt;::type
	&gt;
	, boost::totally_ordered&lt;PtrIterator&lt;IterT&gt;
	, boost::additive&lt;
		PtrIterator&lt;IterT&gt;,
		typename std::iterator_traits&lt;IterT&gt;::difference_type
	, boost::indexable&lt;
		PtrIterator&lt;IterT&gt;,
		typename std::iterator_traits&lt;IterT&gt;::difference_type,
		typename std::iterator_traits&lt;IterT&gt;::reference
	, boost::unit_steppable&lt;PtrIterator&lt;IterT&gt;
	&gt; &gt; &gt; &gt;
{
  // ...
</code></pre>
<p>Die Schreibarbeit erleichtert es jedenfalls extrem. Trotzdem habe ich nicht schlecht gestaunt, als ich fertig war mit allen Basisklassen und Templateparametern hinschreiben. -&gt; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> <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>2. Frage:<br />
Bei Operatoren wie <code>operator +=</code> benutzt ihr da auch die Copy&amp;Swap Technik wie bei <code>operator =</code> ? Also zum Beispiel:</p>
<pre><code class="language-cpp">MyClass&amp; operator +=(MyClass const&amp; obj)
{
  MyClass copy(*this);

  // Addition auf copy durchführen.

  copy.swap(*this);
  return *this;
}
</code></pre>
<p>Ursprünglich habe ich es einfach naiv auch hier übernommen. Bei einem Profilertest kam dann aber heraus, dass hier extrem viel Performance verloren geht. Vor allem auch weil z.B. der <code>operator +</code> über <code>operator +=</code> implementiert ist.</p>
<p>Inzwischen ist es draussen. Grundsätzlich dürfte auch keine Exception hier auftauchen bis auf <code>std::bac_alloc</code> , aber da stürzt mein Programm sowieso ab <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 />
Wenn doch eine Exception auftritt dann eine <code>std::out_of_range</code> , aber dann liegt ein Bug vor. Und meine Unit-Tests haben eigentlich gezeigt, dass alles geht. Also kann ich hier wohl darauf verzichten.</p>
<p>Aber wie ist es sonst? Führt ihr hier auch ein Copy&amp;Swap durch? Weil ein <code>operator +=</code> , bzw. ein <code>operator +</code> , wird wohl deutlich öfter vorkommen bei einer Zahlenklasse, als ein <code>operator =</code> . Zudem erscheint mir die Exceptionsicherheit bei einem <code>operator +</code> ziemlich nutzlos, da hier sowieso auf einer Kopie gearbeitet wird.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/244457/zwei-design-fragen-bei-operatorüberladung</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 00:33:17 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/244457.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 30 Jun 2009 13:57:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 13:57:47 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Ich habe mal wieder zwei Designfragen.</p>
<p>1. Frage:<br />
Ich habe mich nun ernsthaft mal mit den Boost.Operators beschäftigt, nachdem pumuckl die Artikel geschrieben hat. Dabei habe ich mir zum Beispiel ein Hilfsmittel für Iteratoren geschrieben, welche auf einen Zeiger verweisen. Bevor jemand mit Boost.PtrContainer kommt, es geht nicht darum, dass der Container die Zeiger auch besitzt <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 />
Dabei enstand folgende Klasse mit Basisklassen. Ist sowas überhaupt noch lesbar? Ich habe es programmiert, ich kann es lesen, aber ob es andere können, würde mich in diesem Fall schon ein wenig interessieren. Natürlich bevorzugt Leute, welche sich mit Boost.Operators auskennen.</p>
<pre><code class="language-cpp">template&lt;typename IterT&gt;
class PtrIterator
	: public std::iterator&lt;
		std::random_access_iterator_tag,
		typename boost::remove_pointer&lt;
			typename std::iterator_traits&lt;IterT&gt;::value_type
		&gt;::type
	&gt;
	, boost::totally_ordered&lt;PtrIterator&lt;IterT&gt;
	, boost::additive&lt;
		PtrIterator&lt;IterT&gt;,
		typename std::iterator_traits&lt;IterT&gt;::difference_type
	, boost::indexable&lt;
		PtrIterator&lt;IterT&gt;,
		typename std::iterator_traits&lt;IterT&gt;::difference_type,
		typename std::iterator_traits&lt;IterT&gt;::reference
	, boost::unit_steppable&lt;PtrIterator&lt;IterT&gt;
	&gt; &gt; &gt; &gt;
{
  // ...
</code></pre>
<p>Die Schreibarbeit erleichtert es jedenfalls extrem. Trotzdem habe ich nicht schlecht gestaunt, als ich fertig war mit allen Basisklassen und Templateparametern hinschreiben. -&gt; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> <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>2. Frage:<br />
Bei Operatoren wie <code>operator +=</code> benutzt ihr da auch die Copy&amp;Swap Technik wie bei <code>operator =</code> ? Also zum Beispiel:</p>
<pre><code class="language-cpp">MyClass&amp; operator +=(MyClass const&amp; obj)
{
  MyClass copy(*this);

  // Addition auf copy durchführen.

  copy.swap(*this);
  return *this;
}
</code></pre>
<p>Ursprünglich habe ich es einfach naiv auch hier übernommen. Bei einem Profilertest kam dann aber heraus, dass hier extrem viel Performance verloren geht. Vor allem auch weil z.B. der <code>operator +</code> über <code>operator +=</code> implementiert ist.</p>
<p>Inzwischen ist es draussen. Grundsätzlich dürfte auch keine Exception hier auftauchen bis auf <code>std::bac_alloc</code> , aber da stürzt mein Programm sowieso ab <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 />
Wenn doch eine Exception auftritt dann eine <code>std::out_of_range</code> , aber dann liegt ein Bug vor. Und meine Unit-Tests haben eigentlich gezeigt, dass alles geht. Also kann ich hier wohl darauf verzichten.</p>
<p>Aber wie ist es sonst? Führt ihr hier auch ein Copy&amp;Swap durch? Weil ein <code>operator +=</code> , bzw. ein <code>operator +</code> , wird wohl deutlich öfter vorkommen bei einer Zahlenklasse, als ein <code>operator =</code> . Zudem erscheint mir die Exceptionsicherheit bei einem <code>operator +</code> ziemlich nutzlos, da hier sowieso auf einer Kopie gearbeitet wird.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735093</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735093</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 30 Jun 2009 13:57:47 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 14:15:08 GMT]]></title><description><![CDATA[<p>Zu 1: Ich kann es gut lesen, obwohl ich mich mit boost::operators kein Stück auskenne. Nur: So eine Sorte Quellcode macht mir keinen Spaß zu lesen.. <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 2: &quot;+=&quot; implementiere ich &quot;direkt&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735106</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735106</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Tue, 30 Jun 2009 14:15:08 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 15:32:37 GMT]]></title><description><![CDATA[<p>Zu 1.:</p>
<pre><code class="language-cpp">template&lt;typename IterT&gt;
class PtrIterator : public boost::random_access_iterator_helper&lt;
                      PtrIterator&lt;IterT&gt;,  //operand type
                      typename boost::remove_pointer&lt;
                        typename std::iterator_traits&lt;IterT&gt;::value_type
                      &gt;::type,             //value type
                      typename std::iterator_traits&lt;IterT&gt;::difference_type,
                      typename std::iterator_traits&lt;IterT&gt;::pointer,
                      typename std::iterator_traits&lt;IterT&gt;::reference
                    &gt;
{ /* ... */ };
</code></pre>
<p><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 2.: ziemlich sicher nicht. Wenns um Exceptionsafety geht halte ich bei op+= die copy&amp;swap-Technik in den meisten Fällen für etwas grobschlächtig, meistens sind da auch nicht so viele potentielle throw-Kandidaten bei den nötigen Operationen für +=. Schließlich sind die Operatoren meistens für Klassen mit value-semantics gedacht, und die sind in der Regel nicht so super komplex aufgebaut und die nötigen Operationen haben fast sämtlich nothrow-Garantie.<br />
Was hast du denn da für ne Klasse wo du das anwenden möchtest? (Vor allem wo es einen bad_alloc und out_of_range geben kann).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735141</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735141</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 30 Jun 2009 15:32:37 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 15:35:23 GMT]]></title><description><![CDATA[<p>Hallo Dravere,</p>
<p>zum Lesen können: Ja - ich kann es lesen, und habe da auch weiter kein Problem mit.<br />
Es wäre aber wesentlich einfacher zu lesen, wenn Du den 'boost.random_access_iterator_helper' benutzt, das verkürzt das Ganze dramatisch und enthält die benötigten Funktionalitäten.</p>
<p>zum Copy&amp;Swap bei operator+=: Ich sage mal im Prinzip ja. Meistens lege ich aber nicht das ganze Objekt an, sondern nur z.B. einen std::vector, dessen Typ mit dem Aggregat meiner Klasse übereinstimmt - und swappe anschließend den std::vector.<br />
Wenn Du die Performance mit den operator+-Geschichten&amp;Co ernsthaft verbessern willst, bleibt Dir wahrscheinlich sowieso nur die Expression-Template-Technik.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735145</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735145</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Tue, 30 Jun 2009 15:35:23 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 16:01:48 GMT]]></title><description><![CDATA[<p>Zu <code>random_access_iterator_helper</code> :<br />
Ihr vergesst, worum es hier geht. <code>PtrIterator</code> ist da, um einen normalen Iterator zu kapseln, ähnlich wie ein <code>reverse_iterator</code> . Daher müssen <code>operator *()</code> und <code>operator -&gt;()</code> spezialsiert werden, so dass sie den zurückgegebenen Typ nochmals dereferenzieren. Keine Chance sowas mit <code>random_access_iterator_helper</code> hinzubekommen, zumindest habe ich keine sinnvolle gefunden <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><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9960">@pumuckl</a>,<br />
Es geht hier um BCD Zahlen (Marke Pseudoeigenbau). Die haben intern eine <code>std::deque</code> . Wenn nun addiert wird, kann die <code>std::deque</code> grösser oder kleiner werden. Beim &quot;grösser werden&quot; wäre es theoretisch möglich, dass ein <code>std::bad_alloc</code> geworfen wird. Bei <code>std::out_of_range</code> bin ich mir gar nicht mal sicher, ob das Ding überhaupt geworfen wird, da ich grundsätzlich per Iteratoren oder <code>operator []</code> zugreife, welche sowas eigentlich nicht werfen. Aber irgendwie hatte ich es noch im Kopf, dass es eine Möglichkeit gibt. Aber will das jetzt nicht nachprüfen gehen. Theoretisch, also wenn keine Bugs vorhanden sind, sollte nichts geworfen werden.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/7393">@Werner</a> Salomon,<br />
Expression-Template-Technik? Wie es zum Beispiel Boost.Spirit oder Boost.Lambda machen?<br />
Glaub ich weniger, dass dies was bringen würde. Problem ist halt die teuren <code>std::deque</code> Kopien. Es wäre eher eine Überlegung wert, die Speicherverwaltung zu optimieren. Aber bisher funktioniert es ziemlich gut, wenn ich einfach die Copy&amp;Swap Technik fallen lasse, welche mir, wie schon gesagt, in diesem Fall etwas unnötig erscheint.</p>
<p>Ich erweitere aus Interesse noch die Frage 2:<br />
Wie exzessiv setzt ihr eigentlich die Copy&amp;Swap Technik ein? Schreibt ihr jedesmal euren eigenen <code>operator =</code> , statt der vom Kompiler generierten?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735153</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735153</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 30 Jun 2009 16:01:48 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 18:18:47 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Zu <code>random_access_iterator_helper</code> :<br />
Ihr vergesst, worum es hier geht. <code>PtrIterator</code> ist da, um einen normalen Iterator zu kapseln, ähnlich wie ein <code>reverse_iterator</code> . Daher müssen <code>operator *()</code> und <code>operator -&gt;()</code> spezialsiert werden, so dass sie den zurückgegebenen Typ nochmals dereferenzieren. Keine Chance sowas mit <code>random_access_iterator_helper</code> hinzubekommen, zumindest habe ich keine sinnvolle gefunden <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>Meinst du einen iterator, der, wenn man ihn dereferenziert, das objekt zurückgibt, auf das der Pointer zeigt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735190</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735190</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 30 Jun 2009 18:18:47 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 18:30:27 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Meinst du einen iterator, der, wenn man ihn dereferenziert, das objekt zurückgibt, auf das der Pointer zeigt?</p>
</blockquote>
<p>Ehm, wenn ich dich richtig verstanden habe, dann ja.<br />
Ach, ein wenig Code sagt mehr als 1000 Worte:</p>
<pre><code class="language-cpp">std::vector&lt;Foo*&gt; vec;
// füllen

// Bisher:
typedef std::vector&lt;Foo*&gt;::iterator Iter;

{
  Iter iter = vec.begin();
  Iter end = vec.end();

  for(; iter != end; ++iter)
  {
    // -&gt; würde ein Foo** zurückgeben.
    // Daher zuerst dereferenzieren, für ein Foo*
    // und danach den operator -&gt; verwenden.
    (*iter)-&gt;bar();
  }
}

// Mit PtrIterator:
typedef PtrIterator&lt;Iter&gt; PtrIter;

{
  PtrIter iter = vec.begin();
  PtrIter end = vec.end();

  for(; iter != end; ++iter)
  {
    // -&gt; gibt kein Foo** zurück, sondern ein Foo*
    // Klammerung fällt weg.
    iter-&gt;bar();
  }
}
</code></pre>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735193</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735193</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 30 Jun 2009 18:30:27 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 19:06:35 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt;typename IterT&gt;
struct PtrIterator : public boost::random_access_iterator_helper&lt;
                      PtrIterator&lt;IterT&gt;,  //operand type
                      typename boost::remove_pointer&lt;
                        typename std::iterator_traits&lt;IterT&gt;::value_type
                      &gt;::type,             //value type
                      typename std::iterator_traits&lt;IterT&gt;::difference_type
                      /* pointer = value_type*, reference = value_type&amp;*/
                    &gt;
{
  typedef typename boost::remove_pointer&lt;
                     typename std::iterator_traits&lt;IterT&gt;::value_type
                   &gt;::type value_type;

  value_type&amp; operator* () const
  {
    return *(*iter);
  } 

  //rest trivial...

private: 
  IterT&amp; iter;
};
</code></pre>
<p>Rest sollte tun...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735212</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735212</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 30 Jun 2009 19:06:35 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 19:28:36 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Zu <code>random_access_iterator_helper</code> :<br />
Ihr vergesst, worum es hier geht. <code>PtrIterator</code> ist da, um einen normalen Iterator zu kapseln, ähnlich wie ein <code>reverse_iterator</code> . Daher müssen <code>operator *()</code> und <code>operator -&gt;()</code> spezialsiert werden, so dass sie den zurückgegebenen Typ nochmals dereferenzieren. Keine Chance sowas mit <code>random_access_iterator_helper</code> hinzubekommen, zumindest habe ich keine sinnvolle gefunden</p>
</blockquote>
<p>Hallo Dravere,</p>
<p>bei allen boost::*_iterator_helper-Konstruktionen muss operator*() selbst implementiert werden. operator-&gt;() wird aus operator*() generiert. Eine Kapselung eines Iterators, der als value_type einen T* hat, zu einem, der ein T als value_type hat, ist da wirklich eine leichte Übung:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;boost/operators.hpp&gt;
#include &lt;boost/type_traits/remove_pointer.hpp&gt;

struct Foo
{
    void bar() { std::cout &lt;&lt; &quot;bar gerufen ..&quot; &lt;&lt; std::endl; }
};

template&lt; typename T &gt;
class PtrIterator : public boost::random_access_iterator_helper&lt; PtrIterator&lt; T &gt;, 
    typename boost::remove_pointer&lt; typename std::iterator_traits&lt; T &gt;::value_type &gt;::type &gt;
{
public:
    typedef typename boost::remove_pointer&lt; typename std::iterator_traits&lt; T &gt;::value_type &gt;::type value_type;

    /* implicit */ PtrIterator( T base )
        : m_base( base )
    {}
    PtrIterator&amp; operator++()
    {
        ++m_base;
        return *this;
    }
    value_type&amp; operator*() const
    {
        return **m_base;
    }
    bool operator==( const PtrIterator&amp; b ) const
    {
        return m_base == b.m_base;
    }
    PtrIterator&amp; operator+=( std::ptrdiff_t off )
    {
        m_base += off;
        return *this;
    }

    // usw. operator--, operator-=

private:
    T m_base;
};

int main()
{
    using namespace std;
    vector&lt; Foo* &gt; v;
    v.push_back( new Foo );

    typedef std::vector&lt; Foo* &gt;::iterator Iter;
    typedef PtrIterator&lt; Iter &gt; PtrIter;
    for( PtrIter i = v.begin(); i != v.end(); ++i )
        i-&gt;bar();

    return 0;
}
</code></pre>
<p>.. funktioniert einwandfrei <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f576.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--sunglasses"
      title=":sunglasses:"
      alt="🕶"
    /></p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Expression-Template-Technik? Wie es zum Beispiel Boost.Spirit oder Boost.Lambda machen?</p>
</blockquote>
<p>boost.ublas ist so gemacht .. das kommt dem am nächsten, was ich meine.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Glaub ich weniger, dass dies was bringen würde. Problem ist halt die teuren <code>std::deque</code> Kopien.</p>
</blockquote>
<p>Umso eher bringen die Expression-Template was - da fällt das Kopieren von temporären Kopien vollständig weg.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Ich erweitere aus Interesse noch die Frage 2:<br />
Wie exzessiv setzt ihr eigentlich die Copy&amp;Swap Technik ein? Schreibt ihr jedesmal euren eigenen <code>operator =</code> , statt der vom Kompiler generierten?</p>
</blockquote>
<p>.. natürlich nur, wenn es notwendig ist. Ich setze Copy&amp;Swap vornehmlich beim operator= ein, aber auch nur dann, wenn es 'swap'-bare Inhalte habe - also std::container oder ähnliches.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735219</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735219</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Tue, 30 Jun 2009 19:28:36 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Tue, 30 Jun 2009 19:48:25 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Ich erweitere aus Interesse noch die Frage 2:<br />
Wie exzessiv setzt ihr eigentlich die Copy&amp;Swap Technik ein? Schreibt ihr jedesmal euren eigenen <code>operator =</code> , statt der vom Kompiler generierten?</p>
</blockquote>
<p>Copy&amp;swap nur wenns was zu swappen gibt. Ggf. kann man auch die swap-baren member in ein struct kapseln, dessen op= entsprechend implementieren und den Rest dem compilergenerierten op= überlassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735230</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735230</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 30 Jun 2009 19:48:25 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 00:42:18 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9960">@pumuckl</a> &amp; Werner Salomon,<br />
Danke für die Erhellung. Ich habe einen riesigen Denkfehler gemacht. Aber dann wäre dies geklärt.</p>
<p>Werner Salomon schrieb:</p>
<blockquote>
<p>boost.ublas ist so gemacht .. das kommt dem am nächsten, was ich meine.</p>
</blockquote>
<p>Kenne mich mit Boost.uBLAS überhaupt nicht aus. Werde es mir aber dann mal anschauen. Danke für den Hinweis.</p>
<p>Werner Salomon schrieb:</p>
<blockquote>
<p>.. natürlich nur, wenn es notwendig ist.</p>
</blockquote>
<p>Und die Frage ist halt eben, wann ist es notwendig?<br />
Ich meine, Coyp&amp;Swap wird doch in erster Linie dazu eingesetzt, um Exceptionsicherheit zu erzielen. Also keine ungültige Objekte zu erhalten, weil mittem im Kopiervorgang abgebrochen wurde.</p>
<p>Wenn ihr nun davon ausgehen könnt, dass keine Exception geworfen werden kann, ihr aber trotzdem <em>swap</em>-bare Inhalte habt, was macht ihr dann? Geht ihr auf Nummer sicher, weil es vielleicht in Zukunft Änderungen geben könnte und dadurch Exceptions geworfen werden?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735310</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735310</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 01 Jul 2009 00:42:18 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 01:55:26 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Zu <code>random_access_iterator_helper</code> :<br />
Ihr vergesst, worum es hier geht. <code>PtrIterator</code> ist da, um einen normalen Iterator zu kapseln, ähnlich wie ein <code>reverse_iterator</code> . Daher müssen <code>operator *()</code> und <code>operator -&gt;()</code> spezialsiert werden, so dass sie den zurückgegebenen Typ nochmals dereferenzieren. Keine Chance sowas mit <code>random_access_iterator_helper</code> hinzubekommen, zumindest habe ich keine sinnvolle gefunden <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 erklärt wieso du boost::remove_pointer verwendest. Das hab' ich mich nämlich grad ca. 2 Minuten lang gefragt, bevor ich auf die gute Idee gekommen bin, mal die restlichen Beiträge zu lesen. (*)</p>
<p>---</p>
<p>z.T. Lesbarkeit: er. Wie sag ich das jetzt. Ich würde es als &quot;ausreichen lesbar&quot; bezeichnen. Oder als &quot;entzifferbar&quot;. Einfach mal schnell drüberlesen ist nicht drin, es sei denn man kennt die verwendeten Klassen schon gut. Ansonsten muss man zumindest halt machen um mal den einen oder anderen &quot;educated guess&quot; zu machen, was die Template-Klasse XYZ wohl machen wird. Allerdings würde ich sagen dass das vollkommen ausreichen ist, solange verständlich ist, was die Klasse tut. Dann muss ich den Code nämlich garnicht lesen können, es sei denn ich suche Fehler, und das braucht dann sowieso seine Zeit.</p>
<p>*:<br />
Ich würde allerdings einen anderen Namen vorziehen. &quot;PtrIterator&quot; klingt für mich nach einem Iterator der mit Hilfe eines Pointers implementiert ist. Was du machst würde ich wohl eher &quot;DereferencingIterator&quot; nennen.</p>
<p>Was += angeht: kommt drauf an denke ich. Wenn es dir reicht dass dein &quot;PtrIterator&quot; die selben Garantien bezüglich += abgibt wie der &quot;underlying&quot; Iterator, dann sollte ein einfaches weiterreichen an den &quot;underlying&quot; Iterator vollkommen ausreichen, so wie es Werners Code auch macht. Und dann wäre es IMO ziemlich sinnlos hier copy &amp; swap zu verwenden -- selbst wenn es kein Performance-Problem gäbe.</p>
<p>---</p>
<p>BTW: du könntest das ganze noch flexibler machen. Pack die &quot;Transformation&quot; (Dereferenzieren) in eine Traits-Klasse, und implementiere die &quot;TransformingIterator&quot; Klasse so, dass sie auch mit forward oder bidi Iteratoren funktioniert <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="😃"
    /><br />
Dann könnte man z.B. ganz einfach Iteratoren basteln, die das &quot;first&quot; eines std::pair zurückgeben. Oder einen vollkommen sinnfreien, aber sicher lustigen &quot;ROT13&quot; Iterator für Strings machen. Oder halt einfach irgendwas <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1735314</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735314</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 01 Jul 2009 01:55:26 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 10:01:59 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>BTW: du könntest das ganze noch flexibler machen. Pack die &quot;Transformation&quot; (Dereferenzieren) in eine Traits-Klasse, und implementiere die &quot;TransformingIterator&quot; Klasse so, dass sie auch mit forward oder bidi Iteratoren funktioniert</p>
</blockquote>
<p>guter Hinweis, da hätte ich auch gleich drauf kommen können .. und wenn man jetzt noch weiß, dass boost sowas schon fix &amp; fertig anbietet, wird's übersichtlich:</p>
<pre><code class="language-cpp">#include &lt;algorithm&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;boost/iterator/transform_iterator.hpp&gt;

struct Foo
{
    void bar() { std::cout &lt;&lt; &quot;bar gerufen ..&quot; &lt;&lt; std::endl; }
};

template&lt; typename T &gt;
struct DeRef : std::unary_function&lt; T*, T&amp; &gt;
{
    T&amp; operator()( T* p ) const
    {
        return *p;
    }
};

int main()
{
    using namespace std;
    vector&lt; Foo* &gt; v;
    v.push_back( new Foo );

    typedef std::vector&lt; Foo* &gt;::iterator Iter;
    typedef boost::transform_iterator&lt; DeRef&lt; Foo &gt;, Iter &gt; PtrIter;
    const PtrIter iEnd( v.end() );
    for( PtrIter i( v.begin() ); i != iEnd; ++i )
        i-&gt;bar();

    // bzw.:
    for_each( boost::make_transform_iterator( v.begin(), DeRef&lt; Foo &gt;() ),
        boost::make_transform_iterator( v.end(), DeRef&lt; Foo &gt;() ),
        std::mem_fun_ref( &amp;Foo::bar ) );

    // oder mal total einfach und ohne boost
    for_each( v.begin(), v.end(), std::mem_fun( &amp;Foo::bar ) );

    return 0;
}
</code></pre>
<p>und wenn man noch bedenkt, dass die boost::bind-Konstrukte sowohl mit Pointern als auch mit Referenzen zusammenarbeiten (als Alternative zu std::mem_fun[ref]), dann braucht man so einen PtrIterator gar nicht mehr.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735445</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735445</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Wed, 01 Jul 2009 10:01:59 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 12:48:27 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Ich würde allerdings einen anderen Namen vorziehen. &quot;PtrIterator&quot; klingt für mich nach einem Iterator der mit Hilfe eines Pointers implementiert ist. Was du machst würde ich wohl eher &quot;DereferencingIterator&quot; nennen.</p>
</blockquote>
<p>Über die Namenswahl reden wir hier nicht ... <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="😃"
    /><br />
Ich bin ein grauenhaft schlechter Namenswähler. Sieht man auch sehr gut an den Namen meiner Programme ... <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>hustbaer schrieb:</p>
<blockquote>
<p>Dann könnte man z.B. ganz einfach Iteratoren basteln, die das &quot;first&quot; eines std::pair zurückgeben. Oder einen vollkommen sinnfreien, aber sicher lustigen &quot;ROT13&quot; Iterator für Strings machen. Oder halt einfach irgendwas <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>
</blockquote>
<p>Das war aber nicht mein Ziel, mich hat nur dieses <code>(*iter)-&gt;</code> gestört *g*<br />
Die Idee ist aber wirklich gut.</p>
<p>Werner Salomon schrieb:</p>
<blockquote>
<p>.. und wenn man jetzt noch weiß, dass boost sowas schon fix &amp; fertig anbietet, ...</p>
</blockquote>
<p>Was bietet Boost eigentlich nicht an? Ich habe das Gefühl ich lerne über Boost jedesmal was neues. Das ist noch schlimmer als mit C++ selbst <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>Werner Salomon schrieb:</p>
<blockquote>
<p>und wenn man noch bedenkt, dass die boost::bind-Konstrukte sowohl mit Pointern als auch mit Referenzen zusammenarbeiten (als Alternative zu std::mem_fun[ref]), dann braucht man so einen PtrIterator gar nicht mehr.</p>
</blockquote>
<p>Da liegst du falsch. Gut, ich hätte vielleicht irgendwie den einen Algorithmus umbauen können, so dass ich ihn über eine <code>for_each</code> Funktion nehmen kann, aber das wäre mir persönlich zu aufwendig gewesen. Manchmal tut es auch eine schöne altmodische for-Schleife. Man muss ja nicht immer auf Teufel komm raus die Algorithmen aus der Standardbibliothek einsetzen. Daher kann sowas schon sinnvoll sein. Wenn es auch nur zur &quot;Verschönerung&quot; dient. Ich wollte damit wirklich nur das <code>(*iter)-&gt;</code> zu einem <code>iter-&gt;</code> umwandeln. <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>Aber nochmals zurück zum Ursprung. Frage 1 wäre inzwischen wohl geklärt. Da hat meine <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> Reaktion doch irgendwo was sinnvolles bewirkt und das Nachfragen war eine gute Idee <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>Die Antworten auf Frage 2 reichen mir irgendwie noch nicht so ganz. Zum einen wäre eine Antwort auf diese Fragen noch nett:</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Wenn ihr nun davon ausgehen könnt, dass keine Exception geworfen werden kann, ihr aber trotzdem <em>swap</em>-bare Inhalte habt, was macht ihr dann? Geht ihr auf Nummer sicher, weil es vielleicht in Zukunft Änderungen geben könnte und dadurch Exceptions geworfen werden?</p>
</blockquote>
<p>Auch begreife ich nicht ganz, wieso ihr kein Copy&amp;Swap anwenden würdet, wenn es keine <em>swap</em>-baren Member hat. Oder arbeitet ihr dann einfach zuerst auf einer Kopie und weist die Member der Kopie dann einzeln zu, statt einen swap auszuführen? Ich meine, auch bei nicht <em>swap</em>-baren Inhalten kann eine Exception fliegen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735551</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 01 Jul 2009 12:48:27 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 13:41:09 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>Wenn ihr nun davon ausgehen könnt, dass keine Exception geworfen werden kann, ihr aber trotzdem <em>swap</em>-bare Inhalte habt, was macht ihr dann? Geht ihr auf Nummer sicher, weil es vielleicht in Zukunft Änderungen geben könnte und dadurch Exceptions geworfen werden?</p>
</blockquote>
<p>Auch begreife ich nicht ganz, wieso ihr kein Copy&amp;Swap anwenden würdet, wenn es keine <em>swap</em>-baren Member hat. Oder arbeitet ihr dann einfach zuerst auf einer Kopie und weist die Member der Kopie dann einzeln zu, statt einen swap auszuführen? Ich meine, auch bei nicht <em>swap</em>-baren Inhalten kann eine Exception fliegen.</p>
</blockquote>
<p>Aaalso.<br />
Möglichkeit 1: Wenn ich ein simples struct mit nur wenigen Membern hab, also ein &quot;bundle-of-data&quot;, lass ich den op= weg. Den Copy-Ctor auch. Ggf. kommt ein Kommentar hin damit offensichtlich ist, dass ich ihn nicht einfach vergessen hab.<br />
Möglichkeit 2: Ich hab eine Klasse, die einen Copy-Ctor hat. Meist lohnt sich dann ein swap und damit ist C&amp;S ein Dreizeiler.<br />
Möglichkeit 3: Der Profiler sagt mir dass Copy&amp;Swap zu komplex ist, dann kümmere ich mich persönlich drum.</p>
<p>Alles zusammen ist es Schema-F, und das ist auch gut so - Schema-F gibt beim späteren Lesen keine Überraschungen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735591</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735591</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 01 Jul 2009 13:41:09 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 13:46:27 GMT]]></title><description><![CDATA[<p>Irgendwie ist der meiste Code mit boost immer potthässlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735594</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735594</guid><dc:creator><![CDATA[kryptiker]]></dc:creator><pubDate>Wed, 01 Jul 2009 13:46:27 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 14:03:24 GMT]]></title><description><![CDATA[<p>kryptiker schrieb:</p>
<blockquote>
<p>Irgendwie ist der meiste Code mit boost immer potthässlich.</p>
</blockquote>
<p>Das hat Code mit Templates und vielen Templateparametern allgemein an sich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735599</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735599</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 01 Jul 2009 14:03:24 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei Design Fragen bei Operatorüberladung on Wed, 01 Jul 2009 14:53:49 GMT]]></title><description><![CDATA[<p>Werner Salomon schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>BTW: du könntest das ganze noch flexibler machen. Pack die &quot;Transformation&quot; (Dereferenzieren) in eine Traits-Klasse, und implementiere die &quot;TransformingIterator&quot; Klasse so, dass sie auch mit forward oder bidi Iteratoren funktioniert</p>
</blockquote>
<p>guter Hinweis, da hätte ich auch gleich drauf kommen können .. und wenn man jetzt noch weiß, dass boost sowas schon fix &amp; fertig anbietet, wird's übersichtlich:</p>
</blockquote>
<p>Cool. Die Klasse kannte ich auch noch nicht. Hab aber schon halb damit gerechnet dass es sowas in der Boost gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1735620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1735620</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 01 Jul 2009 14:53:49 GMT</pubDate></item></channel></rss>