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<animal> 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("joe") ); 429the_zoo.add_animal( new bird("dodo") ); 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<animal> 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<animal*> std_vec; 446std_vec vec; 447... 448std_vec::iterator i = vec.begin(); 449(*i)->eat(); // '*' needed 450</pre> 451<p>now becomes</p> 452<pre class="literal-block"> 453typedef boost::ptr_vector<animal> ptr_vec; 454ptr_vec vec; 455ptr_vec::iterator i = vec.begin(); 456i->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<animal> 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<animal>::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<animal> 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<animal> set; 492set.insert( new monkey("bobo") ); 493set.insert( new whale("anna") ); 494... 495</pre> 496<p>This requires that <tt class="docutils literal"><span class="pre">operator<()</span></tt> is defined for animals. One 497way to do this could be</p> 498<pre class="literal-block"> 499inline bool operator<( const animal& l, const animal& r ) 500{ 501 return l.name() < 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<std::string,animal> zoo_type; 510zoo_type zoo; 511std::string bobo = "bobo", 512 anna = "anna"; 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( "bobo", // this is bad, but you get compile error 523 new monkey("bobo") ); 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<std::string,animal> animals; 529animals["bobo"].set_name("bobo"); 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<std::string,animal> animals; 542 543using namespace boost::assign; 544ptr_map_insert<monkey>( animals )( "bobo", "bobo" ); 545ptr_map_insert<elephant>( animals )( "bobo", "bobo" ); 546ptr_map_insert<whale>( animals )( "anna", "anna" ); 547ptr_map_insert<emu>( animals )( "anna", "anna" ); 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< boost::nullable<animal> > animals_type; 557animals_type animals; 558... 559animals.insert( animals.end(), new dodo("fido") ); 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->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& 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<animal> 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<monkey> monkeys = boost::assign::ptr_list_of<monkey>( "bobo" )( "bebe")( "uhuh" ); 629boost::ptr_vector<animal> animals = monkeys; 630</pre> 631<p>This also works for maps:</p> 632<pre class="literal-block"> 633boost::ptr_map<std::string,monkey> monkeys = ...; 634boost::ptr_map<std::string,animal> 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->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< nullable<T> >::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>< boost::ptr_deque<animal> > get_zoo() 663{ 664 boost::ptr_deque<animal> result; 665 ... 666 return result.release(); // give up ownership 667} 668... 669boost::ptr_deque<animal> 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 "move-semantics" 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("bibi") ); 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<std::string, boost::nullable<animal> > animal_map; 691animal_map map; 692... 693for( animal_map::const_iterator i = map.begin(), e = map.end(); i != e; ++i ) 694{ 695 std::cout << "\n key: " << i->first; 696 std::cout << "\n age: "; 697 698 if( boost::is_null(i) ) 699 std::cout << "unknown"; 700 else 701 std::cout << i->second->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& bobo = map.at("bobo"); 712} 713catch( boost::bad_ptr_container_operation& e ) 714{ 715 // "bobo" 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><U></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<Base> 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<Derived> 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<Derived> 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<animal> zoo; 753... 754zoo.sort(); // assume 'bool operator<( const animal&, const animal& )' 755zoo.sort( std::less<animal>() ); // 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&, const animal& )' 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<animal> 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