• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version="1.0" encoding="utf-8" ?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
7<title>Boost Pointer Container Library</title>
8<style type="text/css">
9
10/*
11:Author: David Goodger (goodger@python.org)
12:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
13:Copyright: This stylesheet has been placed in the public domain.
14
15Default cascading style sheet for the HTML output of Docutils.
16
17See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
18customize this style sheet.
19*/
20
21/* used to remove borders from tables and images */
22.borderless, table.borderless td, table.borderless th {
23  border: 0 }
24
25table.borderless td, table.borderless th {
26  /* Override padding for "table.docutils td" with "! important".
27     The right padding separates the table cells. */
28  padding: 0 0.5em 0 0 ! important }
29
30.first {
31  /* Override more specific margin styles with "! important". */
32  margin-top: 0 ! important }
33
34.last, .with-subtitle {
35  margin-bottom: 0 ! important }
36
37.hidden {
38  display: none }
39
40.subscript {
41  vertical-align: sub;
42  font-size: smaller }
43
44.superscript {
45  vertical-align: super;
46  font-size: smaller }
47
48a.toc-backref {
49  text-decoration: none ;
50  color: black }
51
52blockquote.epigraph {
53  margin: 2em 5em ; }
54
55dl.docutils dd {
56  margin-bottom: 0.5em }
57
58object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
59  overflow: hidden;
60}
61
62/* Uncomment (and remove this text!) to get bold-faced definition list terms
63dl.docutils dt {
64  font-weight: bold }
65*/
66
67div.abstract {
68  margin: 2em 5em }
69
70div.abstract p.topic-title {
71  font-weight: bold ;
72  text-align: center }
73
74div.admonition, div.attention, div.caution, div.danger, div.error,
75div.hint, div.important, div.note, div.tip, div.warning {
76  margin: 2em ;
77  border: medium outset ;
78  padding: 1em }
79
80div.admonition p.admonition-title, div.hint p.admonition-title,
81div.important p.admonition-title, div.note p.admonition-title,
82div.tip p.admonition-title {
83  font-weight: bold ;
84  font-family: sans-serif }
85
86div.attention p.admonition-title, div.caution p.admonition-title,
87div.danger p.admonition-title, div.error p.admonition-title,
88div.warning p.admonition-title, .code .error {
89  color: red ;
90  font-weight: bold ;
91  font-family: sans-serif }
92
93/* Uncomment (and remove this text!) to get reduced vertical space in
94   compound paragraphs.
95div.compound .compound-first, div.compound .compound-middle {
96  margin-bottom: 0.5em }
97
98div.compound .compound-last, div.compound .compound-middle {
99  margin-top: 0.5em }
100*/
101
102div.dedication {
103  margin: 2em 5em ;
104  text-align: center ;
105  font-style: italic }
106
107div.dedication p.topic-title {
108  font-weight: bold ;
109  font-style: normal }
110
111div.figure {
112  margin-left: 2em ;
113  margin-right: 2em }
114
115div.footer, div.header {
116  clear: both;
117  font-size: smaller }
118
119div.line-block {
120  display: block ;
121  margin-top: 1em ;
122  margin-bottom: 1em }
123
124div.line-block div.line-block {
125  margin-top: 0 ;
126  margin-bottom: 0 ;
127  margin-left: 1.5em }
128
129div.sidebar {
130  margin: 0 0 0.5em 1em ;
131  border: medium outset ;
132  padding: 1em ;
133  background-color: #ffffee ;
134  width: 40% ;
135  float: right ;
136  clear: right }
137
138div.sidebar p.rubric {
139  font-family: sans-serif ;
140  font-size: medium }
141
142div.system-messages {
143  margin: 5em }
144
145div.system-messages h1 {
146  color: red }
147
148div.system-message {
149  border: medium outset ;
150  padding: 1em }
151
152div.system-message p.system-message-title {
153  color: red ;
154  font-weight: bold }
155
156div.topic {
157  margin: 2em }
158
159h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
160h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
161  margin-top: 0.4em }
162
163h1.title {
164  text-align: center }
165
166h2.subtitle {
167  text-align: center }
168
169hr.docutils {
170  width: 75% }
171
172img.align-left, .figure.align-left, object.align-left, table.align-left {
173  clear: left ;
174  float: left ;
175  margin-right: 1em }
176
177img.align-right, .figure.align-right, object.align-right, table.align-right {
178  clear: right ;
179  float: right ;
180  margin-left: 1em }
181
182img.align-center, .figure.align-center, object.align-center {
183  display: block;
184  margin-left: auto;
185  margin-right: auto;
186}
187
188table.align-center {
189  margin-left: auto;
190  margin-right: auto;
191}
192
193.align-left {
194  text-align: left }
195
196.align-center {
197  clear: both ;
198  text-align: center }
199
200.align-right {
201  text-align: right }
202
203/* reset inner alignment in figures */
204div.align-right {
205  text-align: inherit }
206
207/* div.align-center * { */
208/*   text-align: left } */
209
210.align-top    {
211  vertical-align: top }
212
213.align-middle {
214  vertical-align: middle }
215
216.align-bottom {
217  vertical-align: bottom }
218
219ol.simple, ul.simple {
220  margin-bottom: 1em }
221
222ol.arabic {
223  list-style: decimal }
224
225ol.loweralpha {
226  list-style: lower-alpha }
227
228ol.upperalpha {
229  list-style: upper-alpha }
230
231ol.lowerroman {
232  list-style: lower-roman }
233
234ol.upperroman {
235  list-style: upper-roman }
236
237p.attribution {
238  text-align: right ;
239  margin-left: 50% }
240
241p.caption {
242  font-style: italic }
243
244p.credits {
245  font-style: italic ;
246  font-size: smaller }
247
248p.label {
249  white-space: nowrap }
250
251p.rubric {
252  font-weight: bold ;
253  font-size: larger ;
254  color: maroon ;
255  text-align: center }
256
257p.sidebar-title {
258  font-family: sans-serif ;
259  font-weight: bold ;
260  font-size: larger }
261
262p.sidebar-subtitle {
263  font-family: sans-serif ;
264  font-weight: bold }
265
266p.topic-title {
267  font-weight: bold }
268
269pre.address {
270  margin-bottom: 0 ;
271  margin-top: 0 ;
272  font: inherit }
273
274pre.literal-block, pre.doctest-block, pre.math, pre.code {
275  margin-left: 2em ;
276  margin-right: 2em }
277
278pre.code .ln { color: grey; } /* line numbers */
279pre.code, code { background-color: #eeeeee }
280pre.code .comment, code .comment { color: #5C6576 }
281pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
282pre.code .literal.string, code .literal.string { color: #0C5404 }
283pre.code .name.builtin, code .name.builtin { color: #352B84 }
284pre.code .deleted, code .deleted { background-color: #DEB0A1}
285pre.code .inserted, code .inserted { background-color: #A3D289}
286
287span.classifier {
288  font-family: sans-serif ;
289  font-style: oblique }
290
291span.classifier-delimiter {
292  font-family: sans-serif ;
293  font-weight: bold }
294
295span.interpreted {
296  font-family: sans-serif }
297
298span.option {
299  white-space: nowrap }
300
301span.pre {
302  white-space: pre }
303
304span.problematic {
305  color: red }
306
307span.section-subtitle {
308  /* font-size relative to parent (h1..h6 element) */
309  font-size: 80% }
310
311table.citation {
312  border-left: solid 1px gray;
313  margin-left: 1px }
314
315table.docinfo {
316  margin: 2em 4em }
317
318table.docutils {
319  margin-top: 0.5em ;
320  margin-bottom: 0.5em }
321
322table.footnote {
323  border-left: solid 1px black;
324  margin-left: 1px }
325
326table.docutils td, table.docutils th,
327table.docinfo td, table.docinfo th {
328  padding-left: 0.5em ;
329  padding-right: 0.5em ;
330  vertical-align: top }
331
332table.docutils th.field-name, table.docinfo th.docinfo-name {
333  font-weight: bold ;
334  text-align: left ;
335  white-space: nowrap ;
336  padding-left: 0 }
337
338/* "booktabs" style (no vertical lines) */
339table.docutils.booktabs {
340  border: 0px;
341  border-top: 2px solid;
342  border-bottom: 2px solid;
343  border-collapse: collapse;
344}
345table.docutils.booktabs * {
346  border: 0px;
347}
348table.docutils.booktabs th {
349  border-bottom: thin solid;
350  text-align: left;
351}
352
353h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
354h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
355  font-size: 100% }
356
357ul.auto-toc {
358  list-style-type: none }
359
360</style>
361</head>
362<body>
363<div class="document" id="boost-pointer-container-library">
364<h1 class="title"><img alt="Boost" src="boost.png" /> Pointer Container Library</h1>
365<h2 class="subtitle" id="tutorial">Tutorial</h2>
366
367<p>The tutorial shows you the most simple usage of the
368library. It is assumed that the reader is familiar
369with the use of standard containers. Although
370the tutorial is devided into sections, it is recommended
371that you read it all from top to bottom.</p>
372<ul class="simple">
373<li><a class="reference internal" href="#basic-usage">Basic usage</a></li>
374<li><a class="reference internal" href="#indirected-interface">Indirected interface</a></li>
375<li><a class="reference internal" href="#sequence-containers">Sequence containers</a></li>
376<li><a class="reference internal" href="#associative-containers">Associative containers</a></li>
377<li><a class="reference internal" href="#null-values">Null values</a></li>
378<li><a class="reference internal" href="#cloneability">Cloneability</a></li>
379<li><a class="reference internal" href="#new-functions">New functions</a></li>
380<li><a class="reference internal" href="#compatible-smart-pointer-overloads">Compatible smart pointer overloads</a></li>
381<li><a class="reference internal" href="#algorithms">Algorithms</a></li>
382</ul>
383<div class="section" id="basic-usage">
384<h1>Basic usage</h1>
385<p>The most important aspect of a pointer container is that it manages
386memory for you. This means that you in most cases do not need to worry
387about deleting memory.</p>
388<p>Let us assume that we have an OO-hierarchy of animals</p>
389<pre class="literal-block">
390class animal : <a class="reference external" href="http://www.boost.org/libs/utility/utility.htm#Class_noncopyable">boost::noncopyable</a>
391{
392public:
393    virtual      ~animal()   {}
394    virtual void eat()       = 0;
395    virtual int  age() const = 0;
396    // ...
397};
398
399class mammal : public animal
400{
401    // ...
402};
403
404class bird : public animal
405{
406    // ...
407};
408</pre>
409<p>Then the managing of the animals is straight-forward. Imagine a
410Zoo:</p>
411<pre class="literal-block">
412class zoo
413{
414    boost::ptr_vector&lt;animal&gt; the_animals;
415public:
416
417    void add_animal( animal* a )
418    {
419        the_animals.push_back( a );
420    }
421};
422</pre>
423<p>Notice how we just pass the class name to the container; there
424is no <tt class="docutils literal">*</tt> to indicate it is a pointer.
425With this declaration we can now say:</p>
426<pre class="literal-block">
427zoo the_zoo;
428the_zoo.add_animal( new mammal(&quot;joe&quot;) );
429the_zoo.add_animal( new bird(&quot;dodo&quot;) );
430</pre>
431<p>Thus we heap-allocate all elements of the container
432and never rely on copy-semantics.</p>
433</div>
434<div class="section" id="indirected-interface">
435<h1>Indirected interface</h1>
436<p>A particular feature of the pointer containers is that
437the query interface is indirected. For example,</p>
438<pre class="literal-block">
439boost::ptr_vector&lt;animal&gt; vec;
440vec.push_back( new animal ); // you add it as pointer ...
441vec[0].eat();                // but get a reference back
442</pre>
443<p>This indirection also happens to iterators, so</p>
444<pre class="literal-block">
445typedef std::vector&lt;animal*&gt; std_vec;
446std_vec vec;
447...
448std_vec::iterator i = vec.begin();
449(*i)-&gt;eat(); // '*' needed
450</pre>
451<p>now becomes</p>
452<pre class="literal-block">
453typedef boost::ptr_vector&lt;animal&gt;  ptr_vec;
454ptr_vec vec;
455ptr_vec::iterator i = vec.begin();
456i-&gt;eat(); // no indirection needed
457</pre>
458</div>
459<div class="section" id="sequence-containers">
460<h1>Sequence containers</h1>
461<p>The sequence containers are used when you do not need to
462keep an ordering on your elements. You can basically
463expect all operations of the normal standard containers
464to be available. So, for example, with a  <tt class="docutils literal">ptr_deque</tt>
465and <tt class="docutils literal">ptr_list</tt> object you can say:</p>
466<pre class="literal-block">
467boost::ptr_deque&lt;animal&gt; deq;
468deq.push_front( new animal );
469deq.pop_front();
470</pre>
471<p>because <tt class="docutils literal"><span class="pre">std::deque</span></tt> and <tt class="docutils literal"><span class="pre">std::list</span></tt> have <tt class="docutils literal">push_front()</tt>
472and <tt class="docutils literal">pop_front()</tt> members.</p>
473<p>If the standard sequence supports
474random access, so does the pointer container; for example:</p>
475<pre class="literal-block">
476for( boost::ptr_deque&lt;animal&gt;::size_type i = 0u;
477     i != deq.size(); ++i )
478     deq[i].eat();
479</pre>
480<p>The <tt class="docutils literal">ptr_vector</tt> also allows you to specify the size of
481the buffer to allocate; for example</p>
482<pre class="literal-block">
483boost::ptr_vector&lt;animal&gt; animals( 10u );
484</pre>
485<p>will reserve room for 10 animals.</p>
486</div>
487<div class="section" id="associative-containers">
488<h1>Associative containers</h1>
489<p>To keep an ordering on our animals, we could use a <tt class="docutils literal">ptr_set</tt>:</p>
490<pre class="literal-block">
491boost::ptr_set&lt;animal&gt; set;
492set.insert( new monkey(&quot;bobo&quot;) );
493set.insert( new whale(&quot;anna&quot;) );
494...
495</pre>
496<p>This requires that <tt class="docutils literal"><span class="pre">operator&lt;()</span></tt> is defined for animals. One
497way to do this could be</p>
498<pre class="literal-block">
499inline bool operator&lt;( const animal&amp; l, const animal&amp; r )
500{
501    return l.name() &lt; r.name();
502}
503</pre>
504<p>if we wanted to keep the animals sorted by name.</p>
505<p>Maybe you want to keep all the animals in zoo ordered wrt.
506their name, but it so happens that many animals have the
507same name. We can then use a <tt class="docutils literal">ptr_multimap</tt>:</p>
508<pre class="literal-block">
509typedef boost::ptr_multimap&lt;std::string,animal&gt; zoo_type;
510zoo_type zoo;
511std::string bobo = &quot;bobo&quot;,
512            anna = &quot;anna&quot;;
513zoo.insert( bobo, new monkey(bobo) );
514zoo.insert( bobo, new elephant(bobo) );
515zoo.insert( anna, new whale(anna) );
516zoo.insert( anna, new emu(anna) );
517</pre>
518<p>Note that must create the key as an lvalue
519(due to exception-safety issues); the following would not
520have compiled</p>
521<pre class="literal-block">
522zoo.insert( &quot;bobo&quot;, // this is bad, but you get compile error
523            new monkey(&quot;bobo&quot;) );
524</pre>
525<p>If a multimap is not needed, we can use <tt class="docutils literal"><span class="pre">operator[]()</span></tt>
526to avoid the clumsiness:</p>
527<pre class="literal-block">
528boost::ptr_map&lt;std::string,animal&gt; animals;
529animals[&quot;bobo&quot;].set_name(&quot;bobo&quot;);
530</pre>
531<p>This requires a default constructor for animals and
532a function to do the initialization, in this case <tt class="docutils literal">set_name()</tt>.</p>
533<p>A better alternative is to use <a class="reference external" href="../../assign/index.html">Boost.Assign</a>
534to help you out. In particular, consider</p>
535<ul class="simple">
536<li><a class="reference external" href="../../assign/doc/index.html#ptr_push_back">ptr_push_back(), ptr_push_front(), ptr_insert() and ptr_map_insert()</a></li>
537<li><a class="reference external" href="../../assign/doc/index.html#ptr_list_of">ptr_list_of()</a></li>
538</ul>
539<p>For example, the above insertion may now be written</p>
540<pre class="literal-block">
541boost::ptr_multimap&lt;std::string,animal&gt; animals;
542
543using namespace boost::assign;
544ptr_map_insert&lt;monkey&gt;( animals )( &quot;bobo&quot;, &quot;bobo&quot; );
545ptr_map_insert&lt;elephant&gt;( animals )( &quot;bobo&quot;, &quot;bobo&quot; );
546ptr_map_insert&lt;whale&gt;( animals )( &quot;anna&quot;, &quot;anna&quot; );
547ptr_map_insert&lt;emu&gt;( animals )( &quot;anna&quot;, &quot;anna&quot; );
548</pre>
549</div>
550<div class="section" id="null-values">
551<h1>Null values</h1>
552<p>By default, if you try to insert null into a container, an exception
553is thrown. If you want to allow nulls, then you must
554say so explicitly when declaring the container variable</p>
555<pre class="literal-block">
556boost::ptr_vector&lt; boost::nullable&lt;animal&gt; &gt; animals_type;
557animals_type animals;
558...
559animals.insert( animals.end(), new dodo(&quot;fido&quot;) );
560animals.insert( animals.begin(), 0 ) // ok
561</pre>
562<p>Once you have inserted a null into the container, you must
563always check if the value is null before accessing the object</p>
564<pre class="literal-block">
565for( animals_type::iterator i = animals.begin();
566     i != animals.end(); ++i )
567{
568    if( !boost::is_null(i) ) // always check for validity
569        i-&gt;eat();
570}
571</pre>
572<p>If the container support random access, you may also check this as</p>
573<pre class="literal-block">
574for( animals_type::size_type i = 0u;
575     i != animals.size(); ++i )
576{
577    if( !animals.is_null(i) )
578         animals[i].eat();
579}
580</pre>
581<p>Note that it is meaningless to insert
582null into <tt class="docutils literal">ptr_set</tt> and <tt class="docutils literal">ptr_multiset</tt>.</p>
583</div>
584<div class="section" id="cloneability">
585<h1>Cloneability</h1>
586<p>In OO programming it is typical to prohibit copying of objects; the
587objects may sometimes be allowed to be Cloneable; for example,:</p>
588<pre class="literal-block">
589animal* animal::clone() const
590{
591    return do_clone(); // implemented by private virtual function
592}
593</pre>
594<p>If the OO hierarchy thus allows cloning, we need to tell the
595pointer containers how cloning is to be done. This is simply
596done by defining a free-standing function, <tt class="docutils literal">new_clone()</tt>,
597in the same namespace as
598the object hierarchy:</p>
599<pre class="literal-block">
600inline animal* new_clone( const animal&amp; a )
601{
602    return a.clone();
603}
604</pre>
605<p>That is all, now a lot of functions in a pointer container
606can exploit the cloneability of the animal objects. For example</p>
607<pre class="literal-block">
608typedef boost::ptr_list&lt;animal&gt; zoo_type;
609zoo_type zoo, another_zoo;
610...
611another_zoo.assign( zoo.begin(), zoo.end() );
612</pre>
613<p>will fill another zoo with clones of the first zoo. Similarly,
614<tt class="docutils literal">insert()</tt> can now insert clones into your pointer container</p>
615<pre class="literal-block">
616another_zoo.insert( another_zoo.begin(), zoo.begin(), zoo.end() );
617</pre>
618<p>The whole container can now also be cloned</p>
619<pre class="literal-block">
620zoo_type yet_another_zoo = zoo.clone();
621</pre>
622<p>Copying or assigning the container has the same effect as cloning (though it is slightly cheaper):</p>
623<pre class="literal-block">
624zoo_type yet_another_zoo = zoo;
625</pre>
626<p>Copying also support derived-to-base class conversions:</p>
627<pre class="literal-block">
628boost::ptr_vector&lt;monkey&gt; monkeys = boost::assign::ptr_list_of&lt;monkey&gt;( &quot;bobo&quot; )( &quot;bebe&quot;)( &quot;uhuh&quot; );
629boost::ptr_vector&lt;animal&gt; animals = monkeys;
630</pre>
631<p>This also works for maps:</p>
632<pre class="literal-block">
633boost::ptr_map&lt;std::string,monkey&gt; monkeys = ...;
634boost::ptr_map&lt;std::string,animal&gt; animals = monkeys;
635</pre>
636</div>
637<div class="section" id="new-functions">
638<h1>New functions</h1>
639<p>Given that we know we are working with pointers, a few new functions
640make sense. For example, say you want to remove an
641animal from the zoo</p>
642<pre class="literal-block">
643zoo_type::auto_type the_animal = zoo.release( zoo.begin() );
644the_animal-&gt;eat();
645animal* the_animal_ptr = the_animal.release(); // now this is not deleted
646zoo.release(2); // for random access containers
647</pre>
648<p>You can think of <tt class="docutils literal">auto_type</tt> as a non-copyable form of
649<tt class="docutils literal"><span class="pre">std::auto_ptr</span></tt>. Notice that when you release an object, the
650pointer is removed from the container and the containers size
651shrinks. For containers that store nulls, we can exploit that
652<tt class="docutils literal">auto_type</tt> is convertible to <tt class="docutils literal">bool</tt>:</p>
653<pre class="literal-block">
654if( ptr_vector&lt; nullable&lt;T&gt; &gt;::auto_type r = vec.pop_back() )
655{
656  ...
657}
658</pre>
659<p>You can also release the entire container if you
660want to return it from a function</p>
661<pre class="literal-block">
662<a class="reference external" href="compatible_smart_ptr.html"><em>compatible-smart-ptr</em></a>&lt; boost::ptr_deque&lt;animal&gt; &gt; get_zoo()
663{
664    boost::ptr_deque&lt;animal&gt;  result;
665    ...
666    return result.release(); // give up ownership
667}
668...
669boost::ptr_deque&lt;animal&gt; animals = get_zoo();
670</pre>
671<p>Let us assume we want to move an animal object from
672one zoo to another. In other words, we want to move the
673animal and the responsibility of it to another zoo</p>
674<pre class="literal-block">
675another_zoo.transfer( another_zoo.end(), // insert before end
676                      zoo.begin(),       // insert this animal ...
677                      zoo );             // from this container
678</pre>
679<p>This kind of &quot;move-semantics&quot; is different from
680normal value-based containers. You can think of <tt class="docutils literal">transfer()</tt>
681as the same as <tt class="docutils literal">splice()</tt> on <tt class="docutils literal"><span class="pre">std::list</span></tt>.</p>
682<p>If you want to replace an element, you can easily do so</p>
683<pre class="literal-block">
684zoo_type::auto_type old_animal = zoo.replace( zoo.begin(), new monkey(&quot;bibi&quot;) );
685zoo.replace( 2, old_animal.release() ); // for random access containers
686</pre>
687<p>A map is slightly different to iterate over than standard maps.
688Now we say</p>
689<pre class="literal-block">
690typedef boost::ptr_map&lt;std::string, boost::nullable&lt;animal&gt; &gt; animal_map;
691animal_map map;
692...
693for( animal_map::const_iterator i = map.begin(), e = map.end(); i != e; ++i )
694{
695    std::cout &lt;&lt; &quot;\n key: &quot; &lt;&lt; i-&gt;first;
696    std::cout &lt;&lt; &quot;\n age: &quot;;
697
698    if( boost::is_null(i) )
699        std::cout &lt;&lt; &quot;unknown&quot;;
700    else
701        std::cout &lt;&lt; i-&gt;second-&gt;age();
702 }
703</pre>
704<p>Except for the check for null, this looks like it would with a normal map. But if <tt class="docutils literal">age()</tt> had
705not been a <tt class="docutils literal">const</tt> member function,
706it would not have compiled.</p>
707<p>Maps can also be indexed with bounds-checking</p>
708<pre class="literal-block">
709try
710{
711    animal&amp; bobo = map.at(&quot;bobo&quot;);
712}
713catch( boost::bad_ptr_container_operation&amp; e )
714{
715    // &quot;bobo&quot; not found
716}
717</pre>
718</div>
719<div class="section" id="compatible-smart-pointer-overloads">
720<h1>Compatible smart pointer overloads</h1>
721<p>Every time there is a function that takes a <tt class="docutils literal">T*</tt> parameter, there is
722also a function overload (or two) taking a <tt class="docutils literal"><span class="pre"><a class="reference external" href="compatible_smart_ptr.html"><em>compatible-smart-ptr</em></a>&lt;U&gt;</span></tt>
723parameter. This is of course done to make the library intregrate
724seamlessly with <tt class="docutils literal"><span class="pre">std::auto_ptr</span></tt> or <tt class="docutils literal"><span class="pre">std::unique_ptr</span></tt>. For example,
725consider a statement like</p>
726<pre class="literal-block">
727std::ptr_vector&lt;Base&gt; vec;
728vec.push_back( new Base );
729</pre>
730<p>If the compiler supports <tt class="docutils literal"><span class="pre">std::auto_ptr</span></tt>, this is complemented
731by</p>
732<pre class="literal-block">
733std::auto_ptr&lt;Derived&gt; p( new Derived );
734vec.push_back( p );
735</pre>
736<p>Similarly if <tt class="docutils literal"><span class="pre">std::unique_ptr</span></tt> is available, we can write</p>
737<pre class="literal-block">
738std::unique_ptr&lt;Derived&gt; p( new Derived );
739vec.push_back( std::move( p ) );
740</pre>
741<p>Notice that the template argument for <tt class="docutils literal"><span class="pre"><a class="reference external" href="compatible_smart_ptr.html"><em>compatible-smart-ptr</em></a></span></tt> does not need to
742follow the template argument for <tt class="docutils literal">ptr_vector</tt> as long as <tt class="docutils literal">Derived*</tt>
743can be implicitly converted to <tt class="docutils literal">Base*</tt>.</p>
744</div>
745<div class="section" id="algorithms">
746<h1>Algorithms</h1>
747<p>Unfortunately it is not possible to use pointer containers with
748mutating algorithms from the standard library. However,
749the most useful ones
750are instead provided as member functions:</p>
751<pre class="literal-block">
752boost::ptr_vector&lt;animal&gt; zoo;
753...
754zoo.sort();                               // assume 'bool operator&lt;( const animal&amp;, const animal&amp; )'
755zoo.sort( std::less&lt;animal&gt;() );          // the same, notice no '*' is present
756zoo.sort( zoo.begin(), zoo.begin() + 5 ); // sort selected range
757</pre>
758<p>Notice that predicates are automatically wrapped in an <a class="reference external" href="indirect_fun.html">indirect_fun</a> object.</p>
759<p>You can remove equal and adjacent elements using <tt class="docutils literal">unique()</tt>:</p>
760<pre class="literal-block">
761zoo.unique();                             // assume 'bool operator==( const animal&amp;, const animal&amp; )'
762zoo.unique( zoo.begin(), zoo.begin() + 5, my_comparison_predicate() );
763</pre>
764<p>If you just want to remove certain elements, use <tt class="docutils literal">erase_if</tt>:</p>
765<pre class="literal-block">
766zoo.erase_if( my_predicate() );
767</pre>
768<p>Finally you may want to merge two sorted containers:</p>
769<pre class="literal-block">
770boost::ptr_vector&lt;animal&gt; another_zoo = ...;
771another_zoo.sort();                      // sorted wrt. to same order as 'zoo'
772zoo.merge( another_zoo );
773BOOST_ASSERT( another_zoo.empty() );
774</pre>
775<p>That is all; now you have learned all the basics!</p>
776<hr><p><strong>See also</strong></p>
777<ul class="simple">
778<li><a class="reference external" href="guidelines.html">Usage guidelines</a></li>
779<li><a class="reference external" href="../../conversion/cast.htm#Polymorphic_castl">Cast utilities</a></li>
780</ul>
781<p><strong>Navigate</strong></p>
782<ul class="simple">
783<li><a class="reference external" href="ptr_container.html">home</a></li>
784<li><a class="reference external" href="examples.html">examples</a></li>
785</ul>
786<hr><table class="docutils field-list" frame="void" rules="none">
787<col class="field-name" />
788<col class="field-body" />
789<tbody valign="top">
790<tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Thorsten Ottosen 2004-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see <a class="reference external" href="http://www.boost.org/LICENSE_1_0.txt">LICENSE_1_0.txt</a>).</td>
791</tr>
792</tbody>
793</table>
794</div>
795</div>
796</body>
797</html>
798