    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: New Container Classes in Qt 4</title>
        <link>https://members.accu.org/index.php/articles/812</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 17, #3 - Jun 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c96/">173</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-96/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+96/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;New Container Classes in Qt 4</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 June 2005 05:00:00 +01:00 or Thu, 02 June 2005 05:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>In this article, we will review Qt 4's new set of template container classes.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>The next major version of Qt, version 4.0, is expected to be
released in June. Qt 4.0 introduces many new features and many APIs
that have existed ever since version 1.0 have been redesigned.</p>
<p>In this article, we will review Qt 4's new set of template
container classes.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e26" id="d0e26"></a>A Bit of
History</h2>
</div>
<p>Qt 1.0 was released in 1996 with its own container classes.
These classes were used internally by Qt and were part of Qt's
public API as an offer to Qt application developers. They existed
in two versions: A macro-based implementation and a template-based
implementation.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Internally, Qt used the macro-based implementation internally,
because many compilers at the time didn't support templates.</p>
</li>
<li>
<p>The template-based implementation was available to application
writers who were using recent enough compilers.</p>
</li>
</ul>
</div>
<p>Having been developed before STL became part of the C++ Draft
Standard, the Qt 1 container classes had their own original design.
First, they were pointer-based, meaning that they stored pointers
to objects instead of values. For example, a QList&lt;int&gt; was
conceptually equivalent to a std::list&lt;int *&gt;.</p>
<p>In a GUI toolkit, most classes are not copiable (for example,
QObject, QWidget and their subclasses), so it made sense to store
pointer to these. When storing &quot;value&quot; types such as int and
QString, the containers had an &quot;auto-delete&quot; option that you could
turn on to give ownership to your objects to the container.</p>
<p>With Qt 2, the need for value-based collections was addressed by
a new set of container classes inspired by the STL containers. Qt 2
introduced <tt class="classname">QValueList&lt;T&gt;</tt>,
<tt class="classname">QValueStack&lt;T&gt;</tt> and <tt class=
"classname">QMap&lt;K, T&gt;</tt>, with an API that resembled STL a
bit, with some adaptations to Qt's naming conventions (for example,
<tt class="methodname">push_back()</tt> is called <tt class=
"methodname">append()</tt> in Qt). The iterators met the STL axioms
for iterators, ensuring that you could use them in STL algorithms.
Qt 2 also provided a few algorithms of its own, such as <tt class=
"function">qHeapSort()</tt>, for the benefit of application
developers who couldn't rely on the presence of STL.</p>
<p>With Qt 3, we added <tt class=
"classname">QValueVector&lt;T&gt;</tt> and we renamed the
old-style, Qt 1 container classes to include &quot;Ptr&quot; in their name.
<tt class="classname">QList&lt;T&gt;</tt> became <tt class=
"classname">QPtrList&lt;T&gt;</tt>, <tt class=
"classname">QVector&lt;T&gt;</tt> became <tt class=
"classname">QPtrVector&lt;T&gt;</tt>, <tt class=
"classname">QQueue&lt;T&gt;</tt> became <tt class=
"classname">QPtrQueue&lt;T&gt;</tt>, and <tt class=
"classname">QStack&lt;T&gt;</tt> became <tt class=
"classname">QPtrStack&lt;T&gt;</tt>. This step was taken to reduce
confusion and to keep beginners away from these classes.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e91" id="d0e91"></a>Implicit Data
Sharing</h2>
</div>
<p>Unlike existing STL implementations, both sets of Qt containers
(and in fact most Qt tool classes) use an optimization called
implicit data sharing to make copying containers faster.</p>
<p>Implicit sharing takes place behind the scenes in Qt. When you
take a copy of an object, only a pointer to the data is copied; the
actual data is shared by the two objects (the original and the
copy). When either object is modified, the object first takes a
copy of the data, to ensure that the modification will apply only
to this object, not to other objects that shared the data. This is
why this optimization is sometimes called &quot;copy on write&quot;.</p>
<p>Since Qt's container classes are all implicitly shared, you can
pass them around to functions as you will. Because of this,
implicit sharing encourages a programming style where containers
(and other Qt classes such as <tt class="classname">QString</tt>
and <tt class="classname">QImage</tt>) are returned by value:</p>
<pre class="programlisting">
  QMap&lt;QString, int&gt; createCityMap()
  {
    QMap&lt;QString, int&gt; map;
    map[&quot;Tokyo&quot;] = 28025000;
    map[&quot;Mexico City&quot;] = 18131000;
    ...
    return map;
  }
</pre>
<p>The call to the function looks like this:</p>
<pre class="programlisting">
    QMap&lt;QString, int&gt; map = createCityMap();
</pre>
<p>Without implicit sharing, you would be tempted to pass the map
as a non-const reference to avoid the copy that takes place when
the return value is stored in a variable:</p>
<pre class="programlisting">
  void createCityMap(std::map&lt;std::string,
  int&gt; &amp;map)
  {
    map.clear();
    map[&quot;Tokyo&quot;] = 28025000;
    map[&quot;Mexico City&quot;] = 18131000;
    ...
  }
</pre>
<p>The call then becomes:</p>
<pre class="programlisting">
  std::map&lt;std::string, int&gt; map;
  createCityMap(map);
</pre>
<p>Programming like this can rapidly become tedious. It's also
error-prone, because the implementor must remember to call
<tt class="methodname">clear()</tt> at the beginning of the
function.</p>
<p>The main drawback with implicit sharing is that some care must
be taken when copying containers across threads. Qt 3 includes a
class called <tt class="classname">QDeepCopy</tt> that ensures that
no two threads reference the same data simultaneously, but it is
the application developer's job to remember to use this class when
appropriate.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e130" id="d0e130"></a>The Qt 4
Way</h2>
</div>
<p>When we started working on Qt 4, the first issue we had to
address was that of the container classes and the other tool
classes (notably QString). Two of the main goals with Qt 4 were to
provide a nicer API that can compete advantageously with newer
toolkits and to make Qt more efficient, a requirement from Qt's
embedded market.</p>
<p>One option was to deprecate Qt's container classes and to tell
our users to use STL. This had many advantages, but also brought
its share of issues:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Existing Qt users are familiar with Qt's API and many of them
prefer their container classes to have a Qt-like API.</p>
</li>
<li>
<p>STL is not available on some embedded platforms (needed for
Qt/Embedded).</p>
</li>
<li>
<p>Implementations of STL vary quite a bit, meaning that an
application developed on a certain platform might not compile on
another because of some advanced STL construct.</p>
</li>
<li>
<p>STL is usually implemented with raw speed in mind, at the
expense of memory usage and code expansion (the &quot;code bloat&quot;
problem).</p>
</li>
<li>
<p>STL containers aren't implicitly shared.</p>
</li>
</ul>
</div>
<p>For those reasons, we decided to write our own set of containers
for Qt 4, which would replace the previous Qt containers and offer
a solid alternative to STL. The new containers have the following
advantages:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The containers provide new iterators with a nicer, less
error-prone syntax than STL, inspired by Java's iterators. (The
STL-style iterators are still available as a lightweight,
STL-compatible alternative.)</p>
</li>
<li>
<p>The containers have been optimized for minimal code
expansion.</p>
</li>
<li>
<p>An empty container performs no memory allocation, and only
requires the same space as a pointer.</p>
</li>
<li>
<p>Even though they are implicitly shared, they can safely be
copied across different threads without formality. There's no need
to use QDeepCopy. This is possible by using atomic reference
counting, implemented in assembly language.</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e168" id="d0e168"></a>The Container
Classes</h2>
</div>
<p>Qt 4.0 provides the container classes shown in Table 1,
overleaf.</p>
<div class="table"><a name="d0e173" id="d0e173"></a>
<table summary="QT4.0 Container Classes" border="1" cellspacing=
"0">
&lt;colgroup&gt;
&lt;col width=&quot;50%&quot;&gt;
&lt;col width=&quot;50%&quot;&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th align="center">Class</th>
<th align="center">Summary</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td><tt class="classname">QList&lt;T&gt;</tt></td>
<td>This is by far the most commonly used container class. It
stores a list of values of a given type (<tt class=
"literal">T</tt>) that can be accessed by index. Internally, the
<tt class="classname">QList</tt> is implemented using an array,
ensuring that index-based access is very fast.</td>
</tr>
<tr>
<td><tt class="classname">QLinkedList&lt;T&gt;</tt></td>
<td>This is similar to <tt class="classname">QList</tt>, except
that it uses iterators rather than integer indexes to access items.
It also provides better performance than <tt class=
"classname">QList</tt> when inserting in the middle of a huge list,
and it has nicer iterator semantics.</td>
</tr>
<tr>
<td><tt class="classname">QVector&lt;T&gt;</tt></td>
<td>This stores an array of values of a given type at adjacent
positions in memory. Inserting at the front or in the middle of a
vector can be quite slow, because it can lead to large numbers of
items having to be moved by one position in memory.</td>
</tr>
<tr>
<td><tt class="classname">QStack&lt;T&gt;</tt></td>
<td>This is a convenience subclass of <tt class=
"classname">QVector</tt> that provides &quot;last in, first out&quot; (LIFO)
semantics. It adds the following functions to those already present
in <tt class="classname">QVector</tt>: <tt class=
"methodname">push()</tt>, <tt class="methodname">pop()</tt> and
<tt class="methodname">top()</tt>.</td>
</tr>
<tr>
<td><tt class="classname">QQueue&lt;T&gt;</tt></td>
<td>This is a convenience subclass of <tt class=
"classname">QList</tt> that provides &quot;first in, first out&quot; (FIFO)
semantics. It adds the following functions to those already present
in <tt class="classname">QList</tt>: <tt class=
"methodname">enqueue()</tt>, <tt class="methodname">dequeue()</tt>
and <tt class="methodname">head()</tt>.</td>
</tr>
<tr>
<td><tt class="classname">QSet&lt;T&gt;</tt></td>
<td>This provides a single-valued mathematical set with fast
lookups.</td>
</tr>
<tr>
<td><tt class="classname">QMap&lt;Key, T&gt;</tt></td>
<td>This provides a dictionary (associative array) that maps keys
of type Key to values of type <tt class="literal">T</tt>. Normally
each key is associated with a single value. <tt class=
"classname">QMap</tt> stores its data in Key order; if order
doesn't matter <tt class="classname">QHash</tt> is a faster
alternative.</td>
</tr>
<tr>
<td><tt class="classname">QMultiMap&lt;Key, T&gt;</tt></td>
<td>This is a convenience subclass of <tt class=
"classname">QMap</tt> that provides a nice interface for
multi-valued maps, i.e. maps where one key can be associated with
multiple values.</td>
</tr>
<tr>
<td><tt class="classname">QMap&lt;Key, T&gt;</tt></td>
<td>This has almost the same API as <tt class=
"classname">QMap</tt>, but provides significantly faster lookups.
<tt class="classname">QHash</tt> stores its data in an arbitrary
order.</td>
</tr>
<tr>
<td><tt class="classname">QMultiHash&lt;Key, T&gt;</tt></td>
<td>This is a convenience subclass of <tt class=
"classname">QHash</tt> that provides a nice interface for
multi-valued hashes.</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c3">Table 1. QT4.0 Container Classes</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e307" id="d0e307"></a>Algorithmic
Complexity</h2>
</div>
<p>Table 2 summarizes the algorithmic complexity of index-based
lookups, insertions in the middle, prepending and appending for Qt
4's sequential containers:</p>
<div class="table"><a name="d0e312" id="d0e312"></a>
<table summary="Algorithmic Complexity of QT4.0 Container Classes"
border="1" cellspacing="0">
&lt;colgroup&gt;
&lt;col width=&quot;20%&quot;&gt;
&lt;col width=&quot;20%&quot;&gt;
&lt;col width=&quot;20%&quot;&gt;
&lt;col width=&quot;20%&quot;&gt;
&lt;col width=&quot;20%&quot;&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th align="center"> </th>
<th>Lookup</th>
<th align="center">Insert</th>
<th align="center">Prepend</th>
<th align="center">Append</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td><tt class="classname">QLinkedList&lt;T&gt;</tt></td>
<td>O(n)</td>
<td>O(1)</td>
<td>O(1)</td>
<td>O(1)</td>
</tr>
<tr>
<td><tt class="classname">QList&lt;T&gt;</tt></td>
<td>O(1)</td>
<td>O(n)</td>
<td>amortized O(1)</td>
<td>amortized O(1)</td>
</tr>
<tr>
<td><tt class="classname">QVector&lt;T&gt;</tt></td>
<td>O(1)</td>
<td>O(n)</td>
<td>O(n)</td>
<td>amortized O(1)</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c3">Table 2. Algorithmic Complexity of QT4.0
Container Classes</p>
</div>
<p>From the table above, it might look like insertions in the
middle are much faster using <tt class=
"classname">QLinkedList&lt;T&gt;</tt> than using <tt class=
"classname">QList&lt;T&gt;</tt>. However, in practice, for lists of
about a hundred items, both offer more or less the same speed for
insertion in the middle. For lists smaller than that,
QList&lt;T&gt; is faster.</p>
<p>The final table, Table 3, covers Qt 4's associative
containers.</p>
<div class="table"><a name="d0e374" id="d0e374"></a>
<table summary="Associative Containers" border="1" cellspacing="0">
&lt;colgroup&gt;
&lt;col width=&quot;33%&quot;&gt;
&lt;col width=&quot;33%&quot;&gt;
&lt;col width=&quot;34%&quot;&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th align="center"> </th>
<th align="center">Lookup</th>
<th align="center">Insert</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td><tt class="classname">QMap&lt;Key, T&gt;</tt></td>
<td>O(log n)</td>
<td>O(log n)</td>
</tr>
<tr>
<td><tt class="classname">QHash&lt;Key, T&gt;</tt></td>
<td>O(1) on average</td>
<td>amortized O(log n) on average</td>
</tr>
<tr>
<td><tt class="classname">QSet&lt;T&gt;</tt></td>
<td>O(1) on average</td>
<td>amortized O(log n) on average</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c3">Table 3. Associative Containers</p>
</div>
<p>It is possible to get amortized O(1) behavior on average for
insertions into a <tt class="classname">QHash&lt;Key, T&gt;</tt> or
a <tt class="classname">QSet&lt;T&gt;</tt> by setting the number of
buckets in the internal hash table to a suitably large integer
before performing the insertions.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e418" id="d0e418"></a>Pros and Cons
of STL Iterators</h2>
</div>
<p>The main advantage of STL iterators over any other type of
iterators is that you can use them together with STL generic
algorithms (defined in <tt class=
"filename">&lt;algorithm&gt;</tt>). For example, if you want to
sort all the items in a <tt class=
"classname">QVector&lt;int&gt;</tt>, you can call <tt class=
"function">sort()</tt> as follows:</p>
<pre class="programlisting">
  QVector&lt;int&gt; vector;
  vector &lt;&lt; 3 &lt;&lt; 1 &lt;&lt; 4 &lt;&lt; 1 &lt;&lt; 5 &lt;&lt; 9 &lt;&lt; 2;

  sort(vector.begin(), vector.end());
  // vector: [1, 1, 2, 3, 4, 5, 9]
</pre>
<p>Qt 4 also provides a set of generic algorithms in <tt class=
"filename">&lt;QtAlgorithms&gt;</tt>. This is useful if you build
your software on platforms that don't provide an STL implementation
(e.g., on Qt/Embedded).</p>
<p>Each Qt 4 container QXxx has two STL-style iterator classes:
<tt class="classname">QXxx::iterator</tt> and <tt class=
"classname">QXxx::const_iterator</tt>:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>the non-<tt class="literal">const</tt> iterator can be used to
modify the container while iterating;</p>
</li>
<li>
<p>the <tt class="literal">const</tt> iterator should be used for
read-only access.</p>
</li>
</ul>
</div>
<p>The three main advantages of Qt's STL-style iterators are that
they are compatible with STL's generic algorithms, that they are
implemented very efficiently (an STL iterator is typically just
syntactic sugar for a pointer), and that most C++/Qt programmers
are already familiar with them. But they have some disadvantages as
well.</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Modifying a container using a non-const STL iterator is
notoriously error-prone. For example, the following code might skip
one item, or skip the &quot;end&quot; item and crash:</p>
<pre class="programlisting">
// WRONG
for (i = list.begin(); i != list.end(); ++i) {
  if (*i &gt; threshold)
    i = list.erase(i);
}
</pre>
<p>It must be written as follows:</p>
<pre class="programlisting">
i = list.begin();
while (i != list.end()) {
  if (*i &gt; threshold)
    i = list.erase(i);
  else
    ++i;
}
</pre></li>
<li>
<p>Iterating forward and backward are not symmetric.</p>
<p>When iterating backward, you must decrement the iterator before
you access the item. For example:</p>
<p><span class="bold"><b>Forward</b></span></p>
<pre class="programlisting">
i = list.begin();
while (i != list.end()) {
  bamboozle(*i);
  ++i;
}
</pre>
<p><span class="bold"><b>Backward</b></span></p>
<pre class="programlisting">
i = list.end();
while (i != list.begin()) {
  -i;
  bamboozle(*i);
}
</pre>
<p>The STL addresses this problem by providing a <tt class=
"classname">reverse_iterator&lt;T&gt;</tt> iterator adaptor that
wraps an iterator type to make it iterate backward, as well as
<tt class="methodname">rbegin()</tt> and <tt class=
"methodname">rend()</tt> functions in its containers. This enables
you to write</p>
<pre class="programlisting">
i = list.rbegin();
while (i != list.rend()) {
  bamboozle(*i);
  ++i;
}
</pre>
<p>However, this solution requires two additional iterator types,
<tt class="classname">reverse_iterator</tt> and <tt class=
"classname">const_reverse_iterator</tt>.</p>
</li>
<li>
<p>Many users find the operator-based syntax cumbersome. The
operator-based syntax is especially cumbersome when the value type
is a pointer, because you then need to dereference the iterator
twice -once to get the pointer and once to get the object.</p>
<p>For example:</p>
<pre class="programlisting">
QList&lt;QWidget *&gt; list;
...
QList&lt;QWidget *&gt;::iterator i = list.begin();
while (i != list.end()) {
  (*i).show();   // won't compile
  i-&gt;show();     // won't compile
  (**i).show();  // OK
  (*i)-&gt;show();  // OK
  ++i;
}
</pre>
<p>The requirement that you must call both <tt class=
"methodname">begin()</tt> and <tt class="methodname">end()</tt> on
the container object is also a common source of confusion.</p>
<p>For example, the following code typically results in a
crash:</p>
<pre class="programlisting">
// WRONG
i = splitter-&gt;sizes().begin();
while (i != splitter-&gt;sizes().end()) {
  humbug(*i);
  ++i;
}
</pre>
<p>This is because the object on which <tt class=
"methodname">begin()</tt> is called isn't the same as the object on
which <tt class="methodname">end()</tt> is called; <tt class=
"methodname">QSplitter::size()</tt> returns a container by value,
not by reference.</p>
</li>
</ol>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e538" id="d0e538"></a>The Solution:
Java-Style Iterators</h2>
</div>
<p>Qt 4 introduces Java-style iterators as an alternative to
STL-style iterators. As their name suggests, their syntax is
inspired from the Java iterator classes. They attempt to solve the
main issues with STL-style iterators.</p>
<p>Like STL-style iterators, Java-style iterators come in two
variants: a const and a non-const iterator class.</p>
<p>For <tt class="classname">QList&lt;T&gt;</tt>, the Java-style
iterator classes are <tt class=
"classname">QListIterator&lt;T&gt;</tt> and <tt class=
"classname">QListMutableIterator&lt;T&gt;</tt>. Notice that the
shorter name is given to the iterator type that is most frequently
used (the const iterator).</p>
<p>One nice feature of the non-const iterators (the &quot;mutable&quot;
iterators) is that they automatically take a shallow copy of the
container. If you accidentally modify the container while an
iterator is active, the iterator will take a deep copy and continue
iterating over the original data, instead of giving wrong results
or crashing. This makes Java-style iterators less error-prone to
use than STL-style iterators.</p>
<p>The main disadvantage of Java-style iterators is that they
expand to more code in your executables.</p>
<p>Java-style iterators don't point directly at items; instead,
they are located either before or after an item. This eliminates
the need for a &quot;one past the last&quot; item (STL's <tt class=
"methodname">end()</tt>) and makes iterating backward symmetric
with iterating forward.</p>
<p>Let's see how this works in practice. Here's a loop that
computes the sum of all items in a <tt class=
"classname">QList&lt;int&gt;</tt>:</p>
<pre class="programlisting">
    QList&lt;int&gt; list;
    ...
     QListIterator&lt;int&gt; i(list);
        while (i.hasNext())
          sum += i.next();
</pre>
<p>The list is passed to the iterator's constructor. The iterator
is then initialized to the position before the first item. Then we
call <tt class="methodname">hasNext()</tt> to determine whether
there is an item to the right of the iterator, and if so, we call
<tt class="methodname">next()</tt> to obtain that item and advance
the iterator beyond the item. We repeat this operation until the
iterator is located after the last item. At that point, <tt class=
"methodname">hasNext()</tt> returns false.</p>
<p>Iterating backward is similar, except that we must call
<tt class="methodname">toBack()</tt> first to move the iterator to
after the last item:</p>
<pre class="programlisting">
QList&lt;int&gt; list;
 ...
 QListIterator&lt;int&gt; i(list);
 i.toBack();
 while (i.hasPrevious())
   sum += i.previous();
</pre>
<p>The <tt class="methodname">hasPrevious()</tt> function returns
true if there is an item to the left of the current iterator
position; <tt class="methodname">previous()</tt> returns that item
and moves the iterator back by one position. Both <tt class=
"methodname">next()</tt> and <tt class="methodname">previous()</tt>
return the item that was skipped.</p>
<p>Sometimes we need the same item multiple times. We cannot call
<tt class="methodname">next()</tt> or <tt class=
"methodname">previous()</tt> multiple times, because it moves the
iterator in addition to returning the item. The obvious solution is
to store the return value in a variable:</p>
<pre class="programlisting">
while (i.hasNext()) {
  int value = i.next();
  sumSquares += value * value;
}
</pre>
<p>For convenience, the iterator classes offer a <tt class=
"methodname">peekNext()</tt> function that returns the item after
the current iterator position, without side effects. This allows us
to rewrite the code snippet as follows:</p>
<pre class="programlisting">
while (i.hasNext()) {
  sumSquares += i.peekNext() * i.peekNext();
  i.next();
}
</pre>
<p>You can also use <tt class="methodname">peekPrevious()</tt> to
obtain the item before the current iterator position. This gives us
yet another way of writing the &quot;sum squares&quot; code snippet:</p>
<pre class="programlisting">
while (i.hasNext()) {
  i.next();
  sumSquares += i.peekPrevious() * 
      i.peekPrevious();
}
</pre>
<p>So far, we've only seen how to use the const iterator types
(e.g., <tt class="classname">QListIterator&lt;T&gt;</tt>).
Non-const, or mutable, iterators provide the same navigation
functions, but in addition they offer functions to insert, modify,
and remove items from the container.</p>
<p>Let's start with a code snippet that replaces all negative
values in a <tt class="classname">QList&lt;int&gt;</tt> with
zero:</p>
<pre class="programlisting">
QList&lt;int&gt; list;
...
QListMutableIterator&lt;int&gt; i(list);
while (i.hasNext()) {
  if (i.next() &lt; 0)
    i.setValue(0);
}
</pre>
<p>The <tt class="methodname">setValue()</tt> function changes the
value of the last item that was skipped. If we are iterating
forward, this means the item to the left of the new current
position.</p>
<p>When iterating backward, setValue() correctly modifies the item
to the right of the new current position.</p>
<p>For example, the following code snippets replaces all negative
values with zero starting from the end:</p>
<pre class="programlisting">
QListMutableIterator&lt;int&gt; i(list);
i.toBack();
while (i.hasPrevious()) {
  if (i.previous() &lt; 0)
    i.setValue(0);
}
</pre>
<p>First we move the iterator to the back of the list. Then, for
every item, we skip backward past the item and, if its value is
negative, we call <tt class="methodname">setValue()</tt> to set its
value to 0.</p>
<p>Let's now suppose that we want to remove all negative items from
the list. The algorithm is similar, except that this time we call
<tt class="methodname">remove()</tt> instead of <tt class=
"methodname">setValue()</tt>:</p>
<pre class="programlisting">
QListMutableIterator&lt;int&gt; i(list);
while (i.hasNext()) {
  if (i.next() &lt; 0)
    i.remove();
}
</pre>
<p>One strength of Java-style iterators is that after the call to
<tt class="methodname">remove()</tt> we can keep iterating as if
nothing had happened. We can also use <tt class=
"methodname">remove()</tt> when iterating backward:</p>
<pre class="programlisting">
QListMutableIterator&lt;int&gt; i(list);
i.toBack();
while (i.hasPrevious()) {
  if (i.previous() &lt; 0)
    i.remove();
}
</pre>
<p>This time, <tt class="methodname">remove()</tt> affects the item
after the current iterator position, as we would expect. If you
need to find all occurrences of a certain value in a sequential
container (a <tt class="classname">QList</tt>, <tt class=
"classname">QLinkedList</tt>, or <tt class=
"classname">QVector</tt>), you can use <tt class=
"methodname">findNext()</tt> or <tt class=
"methodname">findPrevious()</tt>.</p>
<p>For example, the following loop removes all occurrences of 0 in
a list:</p>
<pre class="programlisting">
while (i.findNext(0))
  i.remove();
</pre>
<p>Qt 4 provides Java-style iterators both for its sequential
containers <tt class="classname">QList</tt>, <tt class=
"classname">QLinkedList</tt>, <tt class="classname">QVector</tt>)
and for its associative containers (<tt class=
"classname">QMap</tt>, <tt class="classname">QHash</tt>). The
associative container iterators work a bit differently to their
sequential counterparts, giving access to both the key and the
value.</p>
<p>In summary, Java-style iterators solve the main issues with
STL-style iterators:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Iterating forward and backward are symmetric operations.</p>
</li>
<li>
<p>Modifying a container using a Java-style iterator is easy and
not error-prone.</p>
</li>
<li>
<p>The Java iterator syntax is highly readable and consistent with
the rest of the Qt API.</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e729" id="d0e729"></a>Foreach
Loops</h2>
</div>
<p>If you just want to iterate over all the items in a container in
order, you can use Qt's foreach keyword. The keyword is a
Qt-specific addition to the C++ language, and is implemented using
the preprocessor. Its syntax is:</p>
<pre class="programlisting">
foreach (variable, container)
  statement
</pre>
<p>For example, here's how to use foreach to iterate over a
<tt class="classname">QLinkedList&lt;QString&gt;</tt>:</p>
<pre class="programlisting">
QLinkedList&lt;QString&gt; list;
...
  QString str;
  foreach (str, list)
    bamboozle(str);
</pre>
<p>Just like C++'s <tt class="literal">for</tt> loop, the variable
used for iteration can be defined within the <tt class=
"literal">foreach</tt> statement. And like any other C++ loop
construct, you can use braces around the body of a <tt class=
"literal">foreach</tt> loop, and you can use break to leave the
loop.</p>
<p>Qt automatically takes a copy of the container when it enters a
<tt class="literal">foreach</tt> loop. If you modify the container
as you are iterating, that won't affect the loop. (If you don't
modify the container, the copy still takes place, but thanks to
implicit sharing copying a container is very fast.)</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
