Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/doc/html/foreach.html @ 66

Last change on this file since 66 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 19.8 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>Chapter 5. Boost.Foreach</title>
5<link rel="stylesheet" href="boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
7<link rel="start" href="index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
8<link rel="up" href="libraries.html" title="Part I. The Boost C++ Libraries (BoostBook Subset)">
9<link rel="prev" href="boost/local_time/posix_time_zone_base.html" title="Class template posix_time_zone_base">
10<link rel="next" href="foreach/extensibility.html" title="Extensibility">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%">
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../boost.png"></td>
15<td align="center"><a href="../../index.htm">Home</a></td>
16<td align="center"><a href="../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="../../people/people.htm">People</a></td>
18<td align="center"><a href="../../more/faq.htm">FAQ</a></td>
19<td align="center"><a href="../../more/index.htm">More</a></td>
20</table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="boost/local_time/posix_time_zone_base.html"><img src="images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="images/home.png" alt="Home"></a><a accesskey="n" href="foreach/extensibility.html"><img src="images/next.png" alt="Next"></a>
24</div>
25<div class="chapter" lang="en">
26<div class="titlepage"><div>
27<div><h2 class="title">
28<a name="foreach"></a>Chapter 5. Boost.Foreach</h2></div>
29<div><div class="author"><h3 class="author">
30<span class="firstname">Eric</span> <span class="surname">Niebler</span>
31</h3></div></div>
32<div><p class="copyright">Copyright © 2004 Eric Niebler</p></div>
33<div><div class="legalnotice">
34<a name="id1180652"></a><p>
35        Distributed under the Boost Software License, Version 1.0. (See accompanying
36        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
37      </p>
38</div></div>
39</div></div>
40<div class="toc">
41<p><b>Table of Contents</b></p>
42<dl>
43<dt><span class="section"><a href="foreach.html#foreach.introduction">Introduction</a></span></dt>
44<dt><span class="section"><a href="foreach/extensibility.html">Extensibility</a></span></dt>
45<dt><span class="section"><a href="foreach/portability.html">Portability</a></span></dt>
46<dt><span class="section"><a href="foreach/pitfalls.html">Pitfalls</a></span></dt>
47<dt><span class="section"><a href="foreach/history_and_acknowledgements.html">History and Acknowledgements</a></span></dt>
48</dl>
49</div>
50<div class="section" lang="en">
51<div class="titlepage"><div><div><h2 class="title" style="clear: both">
52<a name="foreach.introduction"></a>Introduction</h2></div></div></div>
53<div class="blockquote"><blockquote class="blockquote"><p>
54        &#8220;<span class="quote">Make simple things easy.</span>&#8221;<br> <span class="bold"><strong><span class="emphasis"><em>--
55        Larry Wall</em></span></strong></span>
56      </p></blockquote></div>
57<a name="foreach.introduction.what_is__literal_boost_foreach__literal__"></a><h2>
58<a name="id1180706"></a>
59      What is <code class="literal">BOOST_FOREACH</code>?
60    </h2>
61<p>
62      In C++, writing a loop that iterates over a sequence is tedious. We can either
63      use iterators, which requires a considerable amount of boiler-plate, or we
64      can use the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">()</span></code>
65      algorithm and move our loop body into a predicate, which requires no less boiler-plate
66      and forces us to move our logic far from where it will be used. In contrast,
67      some other languages, like Perl, provide a dedicated "foreach" construct
68      that automates this process. <code class="literal">BOOST_FOREACH</code> is just such
69      a construct for C++. It iterates over sequences for us, freeing us from having
70      to deal directly with iterators or write predicates.
71    </p>
72<p>
73      <code class="literal">BOOST_FOREACH</code> is designed for ease-of-use and efficiency.
74      It does no dynamic allocations, makes no virtual function calls or calls through
75      function pointers, and makes no calls that are not transparent to the compiler's
76      optimizer. This results in near-optimal code generation; the performance of
77      <code class="literal">BOOST_FOREACH</code> is usually within a few percent of the equivalent
78      hand-coded loop. And although <code class="literal">BOOST_FOREACH</code> is a macro,
79      it is a remarkably well-behaved one. It evaluates its arguments exactly once,
80      leading to no nasty surprises.
81    </p>
82<a name="foreach.introduction.hello__world_"></a><h2>
83<a name="id1180796"></a>
84      Hello, world!
85    </h2>
86<p>
87      Below is a sample program that uses <code class="literal">BOOST_FOREACH</code> to loop
88      over the contents of a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
89    </p>
90<pre class="programlisting">
91<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
92<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
93<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">foreach</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
94
95<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
96<span class="special">{</span>
97    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">hello</span><span class="special">(</span> <span class="string">"Hello, world!"</span> <span class="special">);</span>
98   
99    <span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">char</span> <span class="identifier">ch</span><span class="special">,</span> <span class="identifier">hello</span> <span class="special">)</span>
100    <span class="special">{</span>
101        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">ch</span><span class="special">;</span>
102    <span class="special">}</span>
103
104    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
105<span class="special">}</span>
106</pre>
107<p>
108      This program outputs the following:
109    </p>
110<pre class="programlisting">Hello, world!
111</pre>
112<a name="foreach.introduction.supported_sequence_types"></a><h2>
113<a name="id1181082"></a>
114      Supported Sequence Types
115    </h2>
116<p>
117      <code class="literal">BOOST_FOREACH</code> iterates over sequences. But what qualifies
118      as a sequence, exactly? Since <code class="literal">BOOST_FOREACH</code> is built on
119      top of <a href="../../libs/range/index.html" target="_top">Boost.Range</a>, it automatically
120      supports those types which <a href="../../libs/range/index.html" target="_top">Boost.Range</a>
121      recognizes as sequences. Specifically, <code class="literal">BOOST_FOREACH</code> works
122      with types that satisfy the <a href="../../libs/range/doc/range.html#single_pass_range" target="_top">Single
123      Pass Range Concept</a>. For example, we can use <code class="literal">BOOST_FOREACH</code>
124      with:
125    </p>
126<div class="itemizedlist"><ul type="disc">
127<li>
128        STL containers
129      </li>
130<li>
131        arrays
132      </li>
133<li>
134        Null-terminated strings (<code class="computeroutput"><span class="keyword">char</span></code>
135        and <code class="computeroutput"><span class="keyword">wchar_t</span></code>)
136      </li>
137<li>
138        std::pair of iterators
139      </li>
140</ul></div>
141<div class="note"><table border="0" summary="Note">
142<tr>
143<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
144<th align="left">Note</th>
145</tr>
146<tr><td align="left" valign="top"><p>
147        The support for STL containers is very general; anything that looks like
148        an STL container counts. If it has nested <code class="computeroutput"><span class="identifier">iterator</span></code>
149        and <code class="computeroutput"><span class="identifier">const_iterator</span></code> types
150        and <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
151        and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>
152        member functions, <code class="literal">BOOST_FOREACH</code> will automatically know
153        how to iterate over it. It is in this way that <a href="../../libs/range/doc/utility_class.html#iter_range" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_range</span><span class="special">&lt;&gt;</span></code></a>
154        and <a href="../../libs/range/doc/utility_class.html#sub_range" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">sub_range</span><span class="special">&lt;&gt;</span></code></a>
155        work with <code class="literal">BOOST_FOREACH</code>.
156      </p></td></tr>
157</table></div>
158<p>
159      See the section on <a href="foreach/extensibility.html" title="Extensibility">Extensibility</a>
160      to find out how to make <code class="literal">BOOST_FOREACH</code> work with other types.
161    </p>
162<a name="foreach.introduction.examples"></a><h2>
163<a name="id1181320"></a>
164      Examples
165    </h2>
166<p>
167      Below are some examples that demonstrate all the different ways we can use
168      <code class="literal">BOOST_FOREACH</code>.
169    </p>
170<p>
171      Iterate over an STL container:
172    </p>
173<pre class="programlisting">
174<span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">list_int</span><span class="special">(</span> <span class="comment">/*...*/</span> <span class="special">);</span>
175<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">list_int</span> <span class="special">)</span>
176<span class="special">{</span>
177    <span class="comment">// do something with i
178</span><span class="special">}</span>
179</pre>
180<p>
181      Iterate over an array, with covariance (i.e., the type of the iteration variable
182      is not exactly the same as the element type of the container):
183    </p>
184<pre class="programlisting">
185<span class="keyword">short</span> <span class="identifier">array_short</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">};</span>
186<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">array_short</span> <span class="special">)</span>
187<span class="special">{</span>
188    <span class="comment">// The short was implicitly converted to an int
189</span><span class="special">}</span>
190</pre>
191<p>
192      Predeclare the loop variable, and use <code class="computeroutput"><span class="keyword">break</span></code>,
193      <code class="computeroutput"><span class="keyword">continue</span></code>, and <code class="computeroutput"><span class="keyword">return</span></code>
194      in the loop body:
195    </p>
196<pre class="programlisting">
197<span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">deque_int</span><span class="special">(</span> <span class="comment">/*...*/</span> <span class="special">);</span>
198<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
199<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">deque_int</span> <span class="special">)</span>
200<span class="special">{</span>
201    <span class="keyword">if</span><span class="special">(</span> <span class="identifier">i</span> <span class="special">==</span> <span class="number">0</span> <span class="special">)</span> <span class="keyword">return</span><span class="special">;</span>
202    <span class="keyword">if</span><span class="special">(</span> <span class="identifier">i</span> <span class="special">==</span> <span class="number">1</span> <span class="special">)</span> <span class="keyword">continue</span><span class="special">;</span>
203    <span class="keyword">if</span><span class="special">(</span> <span class="identifier">i</span> <span class="special">==</span> <span class="number">2</span> <span class="special">)</span> <span class="keyword">break</span><span class="special">;</span>
204<span class="special">}</span>
205</pre>
206<p>
207      Iterate over a sequence by reference, and modify the underlying sequence:
208    </p>
209<pre class="programlisting">
210<span class="keyword">short</span> <span class="identifier">array_short</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">};</span>
211<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">short</span> <span class="special">&amp;</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">array_short</span> <span class="special">)</span>
212<span class="special">{</span>
213    <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
214<span class="special">}</span>
215<span class="comment">// array_short contains {2,3,4} here
216</span></pre>
217<p>
218      Iterate over a vector of vectors with nested <code class="literal">BOOST_FOREACH</code>
219      loops. In this example, notice that braces around the loop body are not necessary:
220    </p>
221<pre class="programlisting">
222<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">matrix_int</span><span class="special">;</span>
223<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">row</span><span class="special">,</span> <span class="identifier">matrix_int</span> <span class="special">)</span>
224    <span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">int</span> <span class="special">&amp;</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">row</span> <span class="special">)</span>
225        <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
226</pre>
227<p>
228      Iterate over an expression that returns a sequence by value (i.e. an rvalue):
229    </p>
230<pre class="programlisting">
231<span class="keyword">extern</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span> <span class="identifier">get_vector_float</span><span class="special">();</span>
232<span class="identifier">BOOST_FOREACH</span><span class="special">(</span> <span class="keyword">float</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">get_vector_float</span><span class="special">()</span> <span class="special">)</span>
233<span class="special">{</span>
234    <span class="comment">// Note: get_vector_float() will be called exactly once
235</span><span class="special">}</span>   
236</pre>
237<p>
238      Iterating over rvalues doesn't work on some older compilers. Check the <a href="foreach/portability.html" title="Portability">Portability</a> section to see whether your
239      compiler supports this.
240    </p>
241<a name="foreach.introduction.making__literal_boost_foreach__literal__prettier"></a><h2>
242<a name="id1182301"></a>
243      Making <code class="literal">BOOST_FOREACH</code> Prettier
244    </h2>
245<p>
246      People have complained about the name <code class="literal">BOOST_FOREACH</code>. It's
247      too long. <code class="computeroutput"><span class="identifier">ALL</span> <span class="identifier">CAPS</span></code>
248      can get tiresome to look at. That may be true, but <code class="literal">BOOST_FOREACH</code>
249      is merely following the <a href="../../../more/lib_guide.htm" target="_top">Boost Naming
250      Convention</a>. That doesn't mean you're stuck with it, though. If you
251      would like to use a different identifier (<code class="computeroutput"><span class="identifier">foreach</span></code>,
252      perhaps), you can simply do:
253    </p>
254<pre class="programlisting">
255<span class="preprocessor">#define</span> <span class="identifier">foreach</span> <span class="identifier">BOOST_FOREACH</span>
256</pre>
257<p>
258      Only do this if you are sure that the identifier you choose will not cause
259      name conflicts in your code.
260    </p>
261<div class="note"><table border="0" summary="Note">
262<tr>
263<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
264<th align="left">Note</th>
265</tr>
266<tr><td align="left" valign="top"><p>
267        Do not use <code class="computeroutput"><span class="preprocessor">#define</span> <span class="identifier">foreach</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">)</span> <span class="identifier">BOOST_FOREACH</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">)</span></code>. This
268        can be problematic if the arguments are macros themselves. This would result
269        in an additional expansion of these macros. Instead, use the form shown above.
270      </p></td></tr>
271</table></div>
272</div>
273</div>
274<table width="100%"><tr>
275<td align="left"><small><p>Last revised: July 16, 2007 at 17:52:43 GMT</p></small></td>
276<td align="right"><small></small></td>
277</tr></table>
278<hr>
279<div class="spirit-nav">
280<a accesskey="p" href="boost/local_time/posix_time_zone_base.html"><img src="images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="images/home.png" alt="Home"></a><a accesskey="n" href="foreach/extensibility.html"><img src="images/next.png" alt="Next"></a>
281</div>
282</body>
283</html>
Note: See TracBrowser for help on using the repository browser.