xref: /openbsd-src/gnu/gcc/libstdc++-v3/docs/html/20_util/howto.html (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert<?xml version="1.0" encoding="ISO-8859-1"?>
2*404b540aSrobert<!DOCTYPE html
3*404b540aSrobert          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4*404b540aSrobert          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5*404b540aSrobert
6*404b540aSrobert<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7*404b540aSrobert<head>
8*404b540aSrobert   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
9*404b540aSrobert   <meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
10*404b540aSrobert   <meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
11*404b540aSrobert   <meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 20." />
12*404b540aSrobert   <meta name="GENERATOR" content="vi and eight fingers" />
13*404b540aSrobert   <title>libstdc++-v3 HOWTO:  Chapter 20: General Utilities</title>
14*404b540aSrobert<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
15*404b540aSrobert<link rel="Start" href="../documentation.html" type="text/html"
16*404b540aSrobert  title="GNU C++ Standard Library" />
17*404b540aSrobert<link rel="Prev" href="../19_diagnostics/howto.html" type="text/html"
18*404b540aSrobert  title="Diagnostics" />
19*404b540aSrobert<link rel="Next" href="../21_strings/howto.html" type="text/html"
20*404b540aSrobert  title="Strings" />
21*404b540aSrobert<link rel="Bookmark" href="allocator.html" type="text/html"
22*404b540aSrobert  title="Allocators and allocation" />
23*404b540aSrobert<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
24*404b540aSrobert<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
25*404b540aSrobert</head>
26*404b540aSrobert<body>
27*404b540aSrobert
28*404b540aSrobert<h1 class="centered"><a name="top">Chapter 20:  General Utilities</a></h1>
29*404b540aSrobert
30*404b540aSrobert<p>Chapter 20 deals with utility classes and functions, such as
31*404b540aSrobert   the oft-debated <code>auto_ptr&lt;&gt;</code>.
32*404b540aSrobert</p>
33*404b540aSrobert
34*404b540aSrobert
35*404b540aSrobert<!-- ####################################################### -->
36*404b540aSrobert<hr />
37*404b540aSrobert<h1>Contents</h1>
38*404b540aSrobert<ul>
39*404b540aSrobert   <li><a href="#1"><code>auto_ptr</code> is not omnipotent</a></li>
40*404b540aSrobert   <li><a href="#2"><code>auto_ptr</code> inside container classes</a></li>
41*404b540aSrobert   <li><a href="#3">Functors</a></li>
42*404b540aSrobert   <li><a href="#4">Pairs</a></li>
43*404b540aSrobert   <li><a href="#5">Memory allocators</a></li>
44*404b540aSrobert</ul>
45*404b540aSrobert
46*404b540aSrobert<hr />
47*404b540aSrobert
48*404b540aSrobert<!-- ####################################################### -->
49*404b540aSrobert
50*404b540aSrobert<h2><a name="1"><code>auto_ptr</code> is not omnipotent</a></h2>
51*404b540aSrobert   <p>I'm not going to try and explain all of the fun and delicious
52*404b540aSrobert      things that can happen with misuse of the auto_ptr class template
53*404b540aSrobert      (called AP here), nor am I going to try and teach you how to use
54*404b540aSrobert      AP safely in the presence of copying.  The AP class is a really
55*404b540aSrobert      nifty idea for a smart pointer, but it is one of the dumbest of
56*404b540aSrobert      all the smart pointers -- and that's fine.
57*404b540aSrobert   </p>
58*404b540aSrobert   <p>AP is not meant to be a supersmart solution to all resource
59*404b540aSrobert      leaks everywhere.  Neither is it meant to be an effective form
60*404b540aSrobert      of garbage collection (although it can help, a little bit).
61*404b540aSrobert      And it can <em>not</em> be used for arrays!
62*404b540aSrobert   </p>
63*404b540aSrobert   <p>AP <em>is</em> meant to prevent nasty leaks in the presence of
64*404b540aSrobert      exceptions.  That's <em>all</em>.  This code is AP-friendly:
65*404b540aSrobert   </p>
66*404b540aSrobert   <pre>
67*404b540aSrobert    // not a recommend naming scheme, but good for web-based FAQs
68*404b540aSrobert    typedef std::auto_ptr&lt;MyClass&gt;  APMC;
69*404b540aSrobert
70*404b540aSrobert    extern function_taking_MyClass_pointer (MyClass*);
71*404b540aSrobert    extern some_throwable_function ();
72*404b540aSrobert
73*404b540aSrobert    void func (int data)
74*404b540aSrobert    {
75*404b540aSrobert        APMC  ap (new MyClass(data));
76*404b540aSrobert
77*404b540aSrobert        some_throwable_function();   // this will throw an exception
78*404b540aSrobert
79*404b540aSrobert        function_taking_MyClass_pointer (ap.get());
80*404b540aSrobert    }
81*404b540aSrobert   </pre>
82*404b540aSrobert   <p>When an exception gets thrown, the instance of MyClass that's
83*404b540aSrobert      been created on the heap will be <code>delete</code>'d as the stack is
84*404b540aSrobert      unwound past <code>func()</code>.
85*404b540aSrobert   </p>
86*404b540aSrobert   <p>Changing that code as follows is <em>not</em> AP-friendly:
87*404b540aSrobert   </p>
88*404b540aSrobert   <pre>
89*404b540aSrobert        APMC  ap (new MyClass[22]);
90*404b540aSrobert   </pre>
91*404b540aSrobert   <p>You will get the same problems as you would without the use
92*404b540aSrobert      of AP:
93*404b540aSrobert   </p>
94*404b540aSrobert   <pre>
95*404b540aSrobert        char*  array = new char[10];       // array new...
96*404b540aSrobert        ...
97*404b540aSrobert        delete array;                      // ...but single-object delete
98*404b540aSrobert   </pre>
99*404b540aSrobert   <p>AP cannot tell whether the pointer you've passed at creation points
100*404b540aSrobert      to one or many things.  If it points to many things, you are about
101*404b540aSrobert      to die.  AP is trivial to write, however, so you could write your
102*404b540aSrobert      own <code>auto_array_ptr</code> for that situation (in fact, this has
103*404b540aSrobert      been done many times; check the mailing lists, Usenet, Boost, etc).
104*404b540aSrobert   </p>
105*404b540aSrobert   <p>Return <a href="#top">to top of page</a> or
106*404b540aSrobert      <a href="../faq/index.html">to the FAQ</a>.
107*404b540aSrobert   </p>
108*404b540aSrobert
109*404b540aSrobert<hr />
110*404b540aSrobert<h2><a name="2"><code>auto_ptr</code> inside container classes</a></h2>
111*404b540aSrobert   <p>All of the <a href="../23_containers/howto.html">containers</a>
112*404b540aSrobert      described in the standard library require their contained types
113*404b540aSrobert      to have, among other things, a copy constructor like this:
114*404b540aSrobert   </p>
115*404b540aSrobert   <pre>
116*404b540aSrobert    struct My_Type
117*404b540aSrobert    {
118*404b540aSrobert        My_Type (My_Type const&amp;);
119*404b540aSrobert    };
120*404b540aSrobert   </pre>
121*404b540aSrobert   <p>Note the const keyword; the object being copied shouldn't change.
122*404b540aSrobert      The template class <code>auto_ptr</code> (called AP here) does not
123*404b540aSrobert      meet this requirement.  Creating a new AP by copying an existing
124*404b540aSrobert      one transfers ownership of the pointed-to object, which means that
125*404b540aSrobert      the AP being copied must change, which in turn means that the
126*404b540aSrobert      copy ctors of AP do not take const objects.
127*404b540aSrobert   </p>
128*404b540aSrobert   <p>The resulting rule is simple:  <em>Never ever use a container of
129*404b540aSrobert      auto_ptr objects.</em>  The standard says that &quot;undefined&quot;
130*404b540aSrobert      behavior is the result, but it is guaranteed to be messy.
131*404b540aSrobert   </p>
132*404b540aSrobert   <p>To prevent you from doing this to yourself, the
133*404b540aSrobert      <a href="../19_diagnostics/howto.html#3">concept checks</a> built
134*404b540aSrobert      in to this implementation will issue an error if you try to
135*404b540aSrobert      compile code like this:
136*404b540aSrobert   </p>
137*404b540aSrobert   <pre>
138*404b540aSrobert    #include &lt;vector&gt;
139*404b540aSrobert    #include &lt;memory&gt;
140*404b540aSrobert
141*404b540aSrobert    void f()
142*404b540aSrobert    {
143*404b540aSrobert        std::vector&lt; std::auto_ptr&lt;int&gt; &gt;   vec_ap_int;
144*404b540aSrobert    }
145*404b540aSrobert   </pre>
146*404b540aSrobert   <p>Should you try this with the checks enabled, you will see an error.
147*404b540aSrobert   </p>
148*404b540aSrobert   <p>Return <a href="#top">to top of page</a> or
149*404b540aSrobert      <a href="../faq/index.html">to the FAQ</a>.
150*404b540aSrobert   </p>
151*404b540aSrobert
152*404b540aSrobert<hr />
153*404b540aSrobert<h2><a name="3">Functors</a></h2>
154*404b540aSrobert   <p>If you don't know what functors are, you're not alone.  Many people
155*404b540aSrobert      get slightly the wrong idea.  In the interest of not reinventing
156*404b540aSrobert      the wheel, we will refer you to the introduction to the functor
157*404b540aSrobert      concept written by SGI as part of their STL, in
158*404b540aSrobert      <a href="http://www.sgi.com/tech/stl/functors.html">their
159*404b540aSrobert      http://www.sgi.com/tech/stl/functors.html</a>.
160*404b540aSrobert   </p>
161*404b540aSrobert   <p>Return <a href="#top">to top of page</a> or
162*404b540aSrobert      <a href="../faq/index.html">to the FAQ</a>.
163*404b540aSrobert   </p>
164*404b540aSrobert
165*404b540aSrobert<hr />
166*404b540aSrobert<h2><a name="4">Pairs</a></h2>
167*404b540aSrobert   <p>The <code>pair&lt;T1,T2&gt;</code> is a simple and handy way to
168*404b540aSrobert      carry around a pair of objects.  One is of type T1, and another of
169*404b540aSrobert      type T2; they may be the same type, but you don't get anything
170*404b540aSrobert      extra if they are.  The two members can be accessed directly, as
171*404b540aSrobert      <code>.first</code> and <code>.second</code>.
172*404b540aSrobert   </p>
173*404b540aSrobert   <p>Construction is simple.  The default ctor initializes each member
174*404b540aSrobert      with its respective default ctor.  The other simple ctor,
175*404b540aSrobert   </p>
176*404b540aSrobert   <pre>
177*404b540aSrobert    pair (const T1&amp; x, const T2&amp; y);
178*404b540aSrobert   </pre>
179*404b540aSrobert   <p>does what you think it does, <code>first</code> getting <code>x</code>
180*404b540aSrobert      and <code>second</code> getting <code>y</code>.
181*404b540aSrobert   </p>
182*404b540aSrobert   <p>There is a copy constructor, but it requires that your compiler
183*404b540aSrobert      handle member function templates:
184*404b540aSrobert   </p>
185*404b540aSrobert   <pre>
186*404b540aSrobert    template &lt;class U, class V&gt; pair (const pair&lt;U,V&gt;&amp; p);
187*404b540aSrobert   </pre>
188*404b540aSrobert   <p>The compiler will convert as necessary from U to T1 and from
189*404b540aSrobert      V to T2 in order to perform the respective initializations.
190*404b540aSrobert   </p>
191*404b540aSrobert   <p>The comparison operators are done for you.  Equality
192*404b540aSrobert      of two <code>pair&lt;T1,T2&gt;</code>s is defined as both <code>first</code>
193*404b540aSrobert      members comparing equal and both <code>second</code> members comparing
194*404b540aSrobert      equal; this simply delegates responsibility to the respective
195*404b540aSrobert      <code>operator==</code> functions (for types like MyClass) or builtin
196*404b540aSrobert      comparisons (for types like int, char, etc).
197*404b540aSrobert   </p>
198*404b540aSrobert   <p><a name="pairlt">
199*404b540aSrobert      The less-than operator is a bit odd the first time you see it.  It
200*404b540aSrobert      is defined as evaluating to:
201*404b540aSrobert      </a>
202*404b540aSrobert   </p>
203*404b540aSrobert   <pre>
204*404b540aSrobert    x.first  &lt;  y.first  ||
205*404b540aSrobert        ( !(y.first  &lt;  x.first)  &amp;&amp;  x.second  &lt;  y.second )
206*404b540aSrobert   </pre>
207*404b540aSrobert   <p>The other operators are not defined using the <code>rel_ops</code>
208*404b540aSrobert      functions above, but their semantics are the same.
209*404b540aSrobert   </p>
210*404b540aSrobert   <p>Finally, there is a template function called <code>make_pair</code>
211*404b540aSrobert      that takes two references-to-const objects and returns an
212*404b540aSrobert      instance of a pair instantiated on their respective types:
213*404b540aSrobert   </p>
214*404b540aSrobert   <pre>
215*404b540aSrobert    pair&lt;int,MyClass&gt; p = make_pair(4,myobject);
216*404b540aSrobert   </pre>
217*404b540aSrobert   <p>Return <a href="#top">to top of page</a> or
218*404b540aSrobert      <a href="../faq/index.html">to the FAQ</a>.
219*404b540aSrobert   </p>
220*404b540aSrobert
221*404b540aSrobert<hr />
222*404b540aSrobert<h2><a name="5">Memory allocators</a></h2>
223*404b540aSrobert   <p>The available free store (&quot;heap&quot;) management classes are
224*404b540aSrobert      described <a href="allocator.html">here</a>.
225*404b540aSrobert   </p>
226*404b540aSrobert   <p>Return <a href="#top">to top of page</a> or
227*404b540aSrobert      <a href="../faq/index.html">to the FAQ</a>.
228*404b540aSrobert   </p>
229*404b540aSrobert
230*404b540aSrobert
231*404b540aSrobert<!-- ####################################################### -->
232*404b540aSrobert
233*404b540aSrobert<hr />
234*404b540aSrobert<p class="fineprint"><em>
235*404b540aSrobertSee <a href="../17_intro/license.html">license.html</a> for copying conditions.
236*404b540aSrobertComments and suggestions are welcome, and may be sent to
237*404b540aSrobert<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
238*404b540aSrobert</em></p>
239*404b540aSrobert
240*404b540aSrobert
241*404b540aSrobert</body>
242*404b540aSrobert</html>
243