<?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[STL-like iterator implementieren]]></title><description><![CDATA[<p>Hallo,</p>
<p>Ich interessiere mich für STL konforme Iteratoren, bzw. wie man diese schreibt.<br />
Ich brauche einen Iterator der als Interface auf einem anderen aufsetzt, und gewisse Dinge evtl. Protokolliert.<br />
Für den Anfang möchte ich einen &quot;Counting Iterator&quot; implementieren, der immer die genaue Position kennt:</p>
<pre><code class="language-cpp">template&lt;class Iterator&gt;
struct CountingIterator : Iterator // z.B. hier, ist Ableitung sinnvoll bzw. vorgesehen?
{
// und hier, gibt es virtuelle Methoden die Ich überladen muss, oder reichen die diversen operatoren (--,++,etc)
}
</code></pre>
<p>Gibt es irgendwo ein Tutorial oder Artikel zu dem Thema?<br />
Wo finde ich genauere Infos zum Iteratorinterface der STL?</p>
<p>mfg.</p>
<p>phlox</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/195507/stl-like-iterator-implementieren</link><generator>RSS for Node</generator><lastBuildDate>Wed, 30 Sep 2026 02:38:27 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/195507.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 18 Oct 2007 12:35:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 12:35:23 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>Ich interessiere mich für STL konforme Iteratoren, bzw. wie man diese schreibt.<br />
Ich brauche einen Iterator der als Interface auf einem anderen aufsetzt, und gewisse Dinge evtl. Protokolliert.<br />
Für den Anfang möchte ich einen &quot;Counting Iterator&quot; implementieren, der immer die genaue Position kennt:</p>
<pre><code class="language-cpp">template&lt;class Iterator&gt;
struct CountingIterator : Iterator // z.B. hier, ist Ableitung sinnvoll bzw. vorgesehen?
{
// und hier, gibt es virtuelle Methoden die Ich überladen muss, oder reichen die diversen operatoren (--,++,etc)
}
</code></pre>
<p>Gibt es irgendwo ein Tutorial oder Artikel zu dem Thema?<br />
Wo finde ich genauere Infos zum Iteratorinterface der STL?</p>
<p>mfg.</p>
<p>phlox</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387867</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387867</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Thu, 18 Oct 2007 12:35:23 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 12:40:17 GMT]]></title><description><![CDATA[<p>Für STL-Iteratoren gibt es keine Basisklasse. Das Interface ist rein syntaktisch festgelegt. Ein bidirektionaler Iterator etwa muß op++, op-- und op* implementieren. Zusätzlich natürlich noch Gleichheit/Ungleichheit, Zuweisung und Copy-Ctor.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387875</guid><dc:creator><![CDATA[Jester]]></dc:creator><pubDate>Thu, 18 Oct 2007 12:40:17 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:01:34 GMT]]></title><description><![CDATA[<p>Die Iteratoren haben keine virtuellen Methoden, nur die typischen<sub>*e*</sub> Operatoren (in meinem Magazin-Artikel &quot;Aufbau der STL - Teil 3&quot; hast du eine Liste, was du brauchst). Übrigens solltest du so einen Hilfs-Iterator nicht per Ableitung einbinden, sondern per Komposition - nimm dir an std::reverse_iterator ein Beispiel (Ableitung wird spätestens dann problematisch, wenn du einen die Position in einem Array mitschreiben willst - dessen Iterator ist ein einfacher Zeiger).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387878</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387878</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:01:34 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:00:16 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>...die typsichen Operatoren ...</p>
</blockquote>
<p>Classic C++: Für &quot;typsicher&quot; und &quot;typisch&quot; braucht man keine getrennten Worte mehr. <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>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387895</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387895</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:00:16 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:04:43 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Die Iteratoren haben keine virtuellen Methoden, nur die typsichen Operatoren (in meinem Magazin-Artikel &quot;Aufbau der STL - Teil 3&quot; hast du eine Liste, was du brauchst). Übrigens solltest du so einen Hilfs-Iterator nicht per Ableitung einbinden, sondern per Komposition - nimm dir an std::reverse_iterator ein Beispiel (Ableitung wird spätestens dann problematisch, wenn du einen die Position in einem Array mitschreiben willst - dessen Iterator ist ein einfacher Zeiger).</p>
</blockquote>
<p>Ok, Ableitung ist damit recht sinnlos.<br />
Komposition heisst dann nichts anderes, als das mein Iterator nur die Aufrufe an diesen weiterleitet, und evtl. vorher entsprechende Checks durchführt?<br />
Wäre dies dann die Implementation?:</p>
<pre><code class="language-cpp">template&lt;typename Iterator&gt;
class CountingIterator : public iterator&lt;bidirectional_iterator_tag,void,void,void,void&gt;
{
protected:
  Iterator&amp; it;
  unsigned int count;
public:
  explicit CountingIterator(Iterator&amp; i) : it(i),count(0) {}

  // Wertzuweisung *it=x
  CountingIterator &amp; operator=(const typename Iterator::value_type&amp; val )
  {
    *it = val;
    return *this;
  }

  //Dereferenzierung
  CountingIterator&amp; operator*() {return *this;}

  //Inkrement
  CountingIterator &amp; operator++() {count++; it++; return *this;}
  CountingIterator &amp; operator++(int) {count++; ++it; return *this;}
  CountingIterator &amp; operator--() {count--; it--; return *this;}
  CountingIterator &amp; operator--(int) {count--; --it; return *this;}
};
</code></pre>
<p>Beim Op* bin ich mir noch nicht sicher, wie ich das an den unterliegenden Iterator weiterleite...</p>
<p>phlox</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387896</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387896</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:04:43 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:09:54 GMT]]></title><description><![CDATA[<p>Simon2 schrieb:</p>
<blockquote>
<p>CStoll schrieb:</p>
<blockquote>
<p>...die typsichen Operatoren ...</p>
</blockquote>
<p>Classic C++: Für &quot;typsicher&quot; und &quot;typisch&quot; braucht man keine getrennten Worte mehr. <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 kommt davon, wenn man sich zu stark bemüht, grammatisch korrekt zu schreiben - die wenigen überlebenden Tipfehler fallen besonders stark auf <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>Edit <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20761">@phlox</a>: Ja, Komposition bedeutet, daß du alle Operationen an einen Member weiterleitest. Aber diese Implementierung funktioniert vermutlich nicht - zumindest die Präfix-Operatoren haben die falsche Semantik (und operator-&gt;() fehlt).</p>
<p>Wie ich schon sagte - schau dir mal std::reverse_iterator&lt;&gt; an, um Anregungen zu holen (zu finden in der &lt;utility&gt;).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387898</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387898</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:09:54 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:37:41 GMT]]></title><description><![CDATA[<p>Hallo phlox,</p>
<p>Die erste Adresse für die Info was ein Iterator ist, ist natürlich der C++-Standard Kapitel 42.1 Iterator requirements.<br />
Außerdem findest Du bei boost einiges darüber. Mit den <a href="http://www.boost.org/libs/utility/operators.htm#deref" rel="nofollow">boost.operators</a> kannst Du leicht eigene Iteratoren bauen und mit [boost.iterators](file:///H:/Toolkit/boost_1_34_0/libs/iterator/doc/index.html) hast Du ein ganzes Iterator construction framework.</p>
<p>Wie CStoll bin auch ich der Meinung, dass Ableitung von einem existierenden Iterator der falsche Weg ist. Eine Komposition wäre hier angebracht.</p>
<p>Anbei ein kleines Beispiel mit einem Output-Iterator - das ist aber auch der einfachste ...</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;iterator&gt; // ostream_iterator
#include &lt;algorithm&gt; // copy
#include &lt;boost/operators.hpp&gt; // output_iterator_helper

template&lt; typename I, typename V &gt;
class CountOut : public boost::output_iterator_helper&lt; CountOut&lt; I, V &gt; &gt;
{
public:
    explicit CountOut( I base ) : m_cnt( 0 ), m_base( base ) {}
    CountOut&amp; operator*()
    {
        return *this;
    }
    CountOut&amp; operator++()
    {
        ++m_base;
        ++m_cnt;
        return *this;
    }
    CountOut&amp; operator=( const V&amp; value )
    {
        *m_base = value;
        return *this;
    }

    int count() const { return m_cnt; }

private:
    int m_cnt;
    I m_base;
};
template&lt; typename V, typename I &gt;
CountOut&lt; I, V &gt; make_countout( I i )
{
    return CountOut&lt; I, V &gt;( i );
}

int main()
{
    using namespace std;
    const char arr[] = &quot;Hallo Welt&quot;;
    int anz = copy( arr, arr + sizeof(arr)/sizeof(*arr) - 1,
        make_countout&lt; char &gt;( ostream_iterator&lt; char &gt;( cout, &quot;.&quot; ) ) ).count();
    cout &lt;&lt; &quot;\n&quot; &lt;&lt; anz &lt;&lt; &quot; mal ein Zeichen mit '.' geschrieben&quot; &lt;&lt; endl;
    return 0;
}
</code></pre>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387927</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387927</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:37:41 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:40:53 GMT]]></title><description><![CDATA[<p>Ja, ein Itertaor ist ja letztendlich auch nur ein Pointer. Man muß eigentlich nur daran denken, die Pointer-Schnittstellen (Operatoren) zu implementieren.</p>
<p>Es gibt aber von Boost auch das <a href="http://www.boost.org/libs/iterator/doc/index.html" rel="nofollow">Iterator Construction Kit</a>. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1387934</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387934</guid><dc:creator><![CDATA[Artchi]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:40:53 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 13:55:08 GMT]]></title><description><![CDATA[<p>Die Boostsachen sehen interessant aus, leider hab ich gerade nicht soviel Zeit mich auch noch in sowas einzulesen <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>Mein aktueller Iterator sieht so aus:</p>
<pre><code class="language-cpp">template&lt;typename Iterator&gt;
class CountingIterator : public std::iterator&lt;typename std::iterator_traits&lt;Iterator&gt;::iterator_category,
		      typename std::iterator_traits&lt;Iterator&gt;::value_type,
		      typename std::iterator_traits&lt;Iterator&gt;::difference_type,
		      typename std::iterator_traits&lt;Iterator&gt;::pointer,
              typename std::iterator_traits&lt;Iterator&gt;::reference&gt;
{
protected:
  Iterator&amp; it;
  unsigned int count;
public:
    typedef typename std::iterator_traits&lt;Iterator&gt;::reference   reference;
    typedef typename std::iterator_traits&lt;Iterator&gt;::pointer     pointer;
  explicit CountingIterator(Iterator&amp; i) : it(i),count(0) {}

  // Wertzuweisung *it=x
  CountingIterator &amp; operator=(const typename Iterator::value_type&amp; val )
  {
    *it = val;
    return *this;
  }

  //Dereferenzierung
  //CountingIterator&amp; operator*() {return *this;}
  reference operator*(){Iterator tmp = it;
	return *--tmp;}

  bool operator!=(const CountingIterator&amp; ci){return it != ci.it;}

  //Inkrement
  CountingIterator &amp; operator++() {count++; it++; return *this;}
  CountingIterator &amp; operator++(int) {count++; ++it; return *this;}
  CountingIterator &amp; operator--() {count--; it--; return *this;}
  CountingIterator &amp; operator--(int) {count--; --it; return *this;}
  unsigned int Getcount()const{return count;}
};
</code></pre>
<p>Problem jedoch ist, das bei:</p>
<pre><code class="language-cpp">int main()
{
	std::string str = &quot;This is a test for the Counting Iterator&quot;;
	std::string::iterator beg,end;
	beg = str.begin();
	end = str.end();
	CountingIterator&lt;std::string::iterator&gt; cbeg(beg),cend(end);
	for(;cbeg != cend;cbeg++)
	{
	    std::cout &lt;&lt; *cbeg &lt;&lt; &quot; &quot; &lt;&lt; cbeg.Getcount() &lt;&lt; std::endl;
    }
	return 0;
}
</code></pre>
<p>...er 1 Element zu früh aufhört...<br />
Woran liegt das?</p>
<p>phlox</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387950</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387950</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Thu, 18 Oct 2007 13:55:08 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 14:09:43 GMT]]></title><description><![CDATA[<p>phlox81 schrieb:</p>
<blockquote>
<p>Wäre dies dann die Implementation?:</p>
<pre><code class="language-cpp">template&lt;typename Iterator&gt;
class CountingIterator : public iterator&lt;bidirectional_iterator_tag,void,void,void,void&gt;
{
</code></pre>
</blockquote>
<p>zum einen solltest Du hier std:: benutzen, da dies sicher in einer H-Datei steht und dort using namespac std nicht angebracht ist und das void,void,void,.. ist so nur für einen Output-Iterator zulässig, aber nicht für einen bidirectional iterator.</p>
<p>phlox81 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">public:
  CountingIterator &amp; operator=(const typename Iterator::value_type&amp; val )
</code></pre>
</blockquote>
<p>hier muss es</p>
<pre><code class="language-cpp">CountingIterator &amp; operator=(const typename std::iterator_traits&lt; Iterator &gt;::value_type&amp; val )
</code></pre>
<p>heißen (mit const) sonst kannst Du hier nicht den Returnwert einer Funktion (z.B. begin()) übergeben. Konsequenterweise darf der Member 'it' dann keine Referenz sein.</p>
<p>phlox81 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">CountingIterator &amp; operator=(const typename Iterator::value_type&amp; val )
</code></pre>
</blockquote>
<p>korrekt wäre hier</p>
<pre><code class="language-cpp">CountingIterator &amp; operator=(const typename std::iterator_traits&lt; Iterator &gt;::value_type&amp; val )
</code></pre>
<p>phlox81 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//Dereferenzierung
  CountingIterator&amp; operator*() {return *this;}
</code></pre>
</blockquote>
<p>Ist nur ok für Output-Iteratoren nicht für bidirektionale Iteratoren</p>
<p>phlox81 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//Inkrement
  CountingIterator &amp; operator++() {count++; it++; return *this;}
  CountingIterator &amp; operator++(int) {count++; ++it; return *this;}
  CountingIterator &amp; operator--() {count--; it--; return *this;}
  CountingIterator &amp; operator--(int) {count--; --it; return *this;}
};
</code></pre>
</blockquote>
<p>Die In/Dekrentoperatoren mit (int) müssen heißen</p>
<pre><code class="language-cpp">CountingIterator operator++(int) { CountingIterator tmp( *this ); this-&gt;operator++(); return tmp;}
</code></pre>
<p>außerdem reicht es in jedem Fall den prefix-++-operator von 'it' zu benutzen.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387964</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387964</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 18 Oct 2007 14:09:43 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 14:17:54 GMT]]></title><description><![CDATA[<p>phlox81 schrieb:</p>
<blockquote>
<p>...er 1 Element zu früh aufhört...<br />
Woran liegt das?<br />
phlox</p>
</blockquote>
<p>wahrscheinlich daran:</p>
<p>phlox81 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//Dereferenzierung
  //CountingIterator&amp; operator*() {return *this;}
  reference operator*(){Iterator tmp = it;
	return *--tmp;}  // &lt;---------------
</code></pre>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1387971</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387971</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 18 Oct 2007 14:17:54 GMT</pubDate></item><item><title><![CDATA[Reply to STL-like iterator implementieren on Thu, 18 Oct 2007 14:34:15 GMT]]></title><description><![CDATA[<p>Jo, das war noch ein C&amp;P Error <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="🙂"
    /> Jetzt klappts.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387991</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387991</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Thu, 18 Oct 2007 14:34:15 GMT</pubDate></item></channel></rss>