]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_traits/doc/html/boost_typetraits/background.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_traits / doc / html / boost_typetraits / background.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Background and Tutorial</title>
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
7 <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.TypeTraits">
8 <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.TypeTraits">
9 <link rel="prev" href="intro.html" title="Introduction">
10 <link rel="next" href="category.html" title="Type Traits by Category">
11 </head>
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../more/index.htm">More</a></td>
20 </tr></table>
21 <hr>
22 <div class="spirit-nav">
23 <a accesskey="p" href="intro.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="category.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="boost_typetraits.background"></a><a class="link" href="background.html" title="Background and Tutorial">Background and Tutorial</a>
28 </h2></div></div></div>
29 <p>
30 The following is an updated version of the article "C++ Type traits"
31 by John Maddock and Steve Cleary that appeared in the October 2000 issue of
32 <a href="http://www.ddj.com" target="_top">Dr Dobb's Journal</a>.
33 </p>
34 <p>
35 Generic programming (writing code which works with any data type meeting a
36 set of requirements) has become the method of choice for providing reusable
37 code. However, there are times in generic programming when "generic"
38 just isn't good enough - sometimes the differences between types are too large
39 for an efficient generic implementation. This is when the traits technique
40 becomes important - by encapsulating those properties that need to be considered
41 on a type by type basis inside a traits class, we can minimize the amount of
42 code that has to differ from one type to another, and maximize the amount of
43 generic code.
44 </p>
45 <p>
46 Consider an example: when working with character strings, one common operation
47 is to determine the length of a null terminated string. Clearly it's possible
48 to write generic code that can do this, but it turns out that there are much
49 more efficient methods available: for example, the C library functions <code class="computeroutput"><span class="identifier">strlen</span></code> and <code class="computeroutput"><span class="identifier">wcslen</span></code>
50 are usually written in assembler, and with suitable hardware support can be
51 considerably faster than a generic version written in C++. The authors of the
52 C++ standard library realized this, and abstracted the properties of <code class="computeroutput"><span class="keyword">char</span></code> and <code class="computeroutput"><span class="keyword">wchar_t</span></code>
53 into the class <code class="computeroutput"><span class="identifier">char_traits</span></code>.
54 Generic code that works with character strings can simply use <code class="computeroutput"><span class="identifier">char_traits</span><span class="special">&lt;&gt;::</span><span class="identifier">length</span></code> to determine the length of a null
55 terminated string, safe in the knowledge that specializations of <code class="computeroutput"><span class="identifier">char_traits</span></code> will use the most appropriate
56 method available to them.
57 </p>
58 <h5>
59 <a name="boost_typetraits.background.h0"></a>
60 <span class="phrase"><a name="boost_typetraits.background.type_traits"></a></span><a class="link" href="background.html#boost_typetraits.background.type_traits">Type
61 Traits</a>
62 </h5>
63 <p>
64 Class <code class="computeroutput"><span class="identifier">char_traits</span></code> is a classic
65 example of a collection of type specific properties wrapped up in a single
66 class - what Nathan Myers termed a <span class="emphasis"><em>baggage class</em></span><a class="link" href="background.html#background.references">[1]</a>. In the Boost type-traits library,
67 we<a class="link" href="background.html#background.references">[2]</a> have written a set of very
68 specific traits classes, each of which encapsulate a single trait from the
69 C++ type system; for example, is a type a pointer or a reference type? Or does
70 a type have a trivial constructor, or a const-qualifier? The type-traits classes
71 share a unified design: each class inherits from the type <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a>
72 if the type has the specified property and inherits from <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a>
73 otherwise. As we will show, these classes can be used in generic programming
74 to determine the properties of a given type and introduce optimizations that
75 are appropriate for that case.
76 </p>
77 <p>
78 The type-traits library also contains a set of classes that perform a specific
79 transformation on a type; for example, they can remove a top-level const or
80 volatile qualifier from a type. Each class that performs a transformation defines
81 a single typedef-member <code class="computeroutput"><span class="identifier">type</span></code>
82 that is the result of the transformation. All of the type-traits classes are
83 defined inside namespace <code class="computeroutput"><span class="identifier">boost</span></code>;
84 for brevity, namespace-qualification is omitted in most of the code samples
85 given.
86 </p>
87 <h5>
88 <a name="boost_typetraits.background.h1"></a>
89 <span class="phrase"><a name="boost_typetraits.background.implementation"></a></span><a class="link" href="background.html#boost_typetraits.background.implementation">Implementation</a>
90 </h5>
91 <p>
92 There are far too many separate classes contained in the type-traits library
93 to give a full implementation here - see the source code in the Boost library
94 for the full details - however, most of the implementation is fairly repetitive
95 anyway, so here we will just give you a flavor for how some of the classes
96 are implemented. Beginning with possibly the simplest class in the library,
97 <code class="computeroutput"><span class="identifier">is_void</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> inherits
98 from <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>
99 only if <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="keyword">void</span></code>.
100 </p>
101 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
102 <span class="keyword">struct</span> <a class="link" href="reference/is_void.html" title="is_void">is_void</a> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a><span class="special">{};</span>
103
104 <span class="keyword">template</span> <span class="special">&lt;&gt;</span>
105 <span class="keyword">struct</span> <a class="link" href="reference/is_void.html" title="is_void">is_void</a><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a><span class="special">{};</span>
106 </pre>
107 <p>
108 Here we define a primary version of the template class <code class="computeroutput"><a class="link" href="reference/is_void.html" title="is_void">is_void</a></code>,
109 and provide a full-specialization when <code class="computeroutput"><span class="identifier">T</span></code>
110 is <code class="computeroutput"><span class="keyword">void</span></code>. While full specialization
111 of a template class is an important technique, sometimes we need a solution
112 that is halfway between a fully generic solution, and a full specialization.
113 This is exactly the situation for which the standards committee defined partial
114 template-class specialization. As an example, consider the class <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_pointer</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>:
115 here we needed a primary version that handles all the cases where T is not
116 a pointer, and a partial specialization to handle all the cases where T is
117 a pointer:
118 </p>
119 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
120 <span class="keyword">struct</span> <a class="link" href="reference/is_pointer.html" title="is_pointer">is_pointer</a> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a><span class="special">{};</span>
121
122 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
123 <span class="keyword">struct</span> <a class="link" href="reference/is_pointer.html" title="is_pointer">is_pointer</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">*&gt;</span> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a><span class="special">{};</span>
124 </pre>
125 <p>
126 The syntax for partial specialization is somewhat arcane and could easily occupy
127 an article in its own right; like full specialization, in order to write a
128 partial specialization for a class, you must first declare the primary template.
129 The partial specialization contains an extra &lt;...&gt; after the class name
130 that contains the partial specialization parameters; these define the types
131 that will bind to that partial specialization rather than the default template.
132 The rules for what can appear in a partial specialization are somewhat convoluted,
133 but as a rule of thumb if you can legally write two function overloads of the
134 form:
135 </p>
136 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span><span class="special">);</span>
137 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">U</span><span class="special">);</span>
138 </pre>
139 <p>
140 Then you can also write a partial specialization of the form:
141 </p>
142 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
143 <span class="keyword">class</span> <span class="identifier">c</span><span class="special">{</span> <span class="comment">/*details*/</span> <span class="special">};</span>
144
145 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
146 <span class="keyword">class</span> <span class="identifier">c</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;{</span> <span class="comment">/*details*/</span> <span class="special">};</span>
147 </pre>
148 <p>
149 This rule is by no means foolproof, but it is reasonably simple to remember
150 and close enough to the actual rule to be useful for everyday use.
151 </p>
152 <p>
153 As a more complex example of partial specialization consider the class <code class="computeroutput"><span class="identifier">remove_extent</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>. This
154 class defines a single typedef-member <code class="computeroutput"><span class="identifier">type</span></code>
155 that is the same type as T but with any top-level array bounds removed; this
156 is an example of a traits class that performs a transformation on a type:
157 </p>
158 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
159 <span class="keyword">struct</span> <a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a>
160 <span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
161
162 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">&gt;</span>
163 <span class="keyword">struct</span> <a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">[</span><span class="identifier">N</span><span class="special">]&gt;</span>
164 <span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
165 </pre>
166 <p>
167 The aim of <code class="computeroutput"><a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a></code>
168 is this: imagine a generic algorithm that is passed an array type as a template
169 parameter, <code class="computeroutput"><a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a></code>
170 provides a means of determining the underlying type of the array. For example
171 <code class="computeroutput"><span class="identifier">remove_extent</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">[</span><span class="number">4</span><span class="special">][</span><span class="number">5</span><span class="special">]&gt;::</span><span class="identifier">type</span></code> would evaluate to the type <code class="computeroutput"><span class="keyword">int</span><span class="special">[</span><span class="number">5</span><span class="special">]</span></code>. This example also shows that the number of
172 template parameters in a partial specialization does not have to match the
173 number in the default template. However, the number of parameters that appear
174 after the class name do have to match the number and type of the parameters
175 in the default template.
176 </p>
177 <h5>
178 <a name="boost_typetraits.background.h2"></a>
179 <span class="phrase"><a name="boost_typetraits.background.optimized_copy"></a></span><a class="link" href="background.html#boost_typetraits.background.optimized_copy">Optimized
180 copy</a>
181 </h5>
182 <p>
183 As an example of how the type traits classes can be used, consider the standard
184 library algorithm copy:
185 </p>
186 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Iter2</span><span class="special">&gt;</span>
187 <span class="identifier">Iter2</span> <span class="identifier">copy</span><span class="special">(</span><span class="identifier">Iter1</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iter1</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">Iter2</span> <span class="identifier">out</span><span class="special">);</span>
188 </pre>
189 <p>
190 Obviously, there's no problem writing a generic version of copy that works
191 for all iterator types <code class="computeroutput"><span class="identifier">Iter1</span></code>
192 and <code class="computeroutput"><span class="identifier">Iter2</span></code>; however, there are
193 some circumstances when the copy operation can best be performed by a call
194 to <code class="computeroutput"><span class="identifier">memcpy</span></code>. In order to implement
195 copy in terms of <code class="computeroutput"><span class="identifier">memcpy</span></code> all
196 of the following conditions need to be met:
197 </p>
198 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
199 <li class="listitem">
200 Both of the iterator types <code class="computeroutput"><span class="identifier">Iter1</span></code>
201 and <code class="computeroutput"><span class="identifier">Iter2</span></code> must be pointers.
202 </li>
203 <li class="listitem">
204 Both <code class="computeroutput"><span class="identifier">Iter1</span></code> and <code class="computeroutput"><span class="identifier">Iter2</span></code> must point to the same type - excluding
205 const and volatile-qualifiers.
206 </li>
207 <li class="listitem">
208 The type pointed to by <code class="computeroutput"><span class="identifier">Iter1</span></code>
209 must have a trivial assignment operator.
210 </li>
211 </ul></div>
212 <p>
213 By trivial assignment operator we mean that the type is either a scalar type<a class="link" href="background.html#background.references">[3]</a> or:
214 </p>
215 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
216 <li class="listitem">
217 The type has no user defined assignment operator.
218 </li>
219 <li class="listitem">
220 The type does not have any data members that are references.
221 </li>
222 <li class="listitem">
223 All base classes, and all data member objects must have trivial assignment
224 operators.
225 </li>
226 </ul></div>
227 <p>
228 If all these conditions are met then a type can be copied using <code class="computeroutput"><span class="identifier">memcpy</span></code> rather than using a compiler generated
229 assignment operator. The type-traits library provides a class <code class="computeroutput"><a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a></code>,
230 such that <code class="computeroutput"><span class="identifier">has_trivial_assign</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code> is true only if T has a trivial assignment
231 operator. This class "just works" for scalar types, but has to be
232 explicitly specialised for class/struct types that also happen to have a trivial
233 assignment operator. In other words if <a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a>
234 gives the wrong answer, it will give the "safe" wrong answer - that
235 trivial assignment is not allowable.
236 </p>
237 <p>
238 The code for an optimized version of copy that uses <code class="computeroutput"><span class="identifier">memcpy</span></code>
239 where appropriate is given in <a class="link" href="examples/copy.html" title="An Optimized Version of std::copy">the
240 examples</a>. The code begins by defining a template function <code class="computeroutput"><span class="identifier">do_copy</span></code> that performs a "slow but safe"
241 copy. The last parameter passed to this function may be either a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>
242 or a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a></code>.
243 Following that there is an overload of do_copy that uses <code class="computeroutput"><span class="identifier">memcpy</span></code>:
244 this time the iterators are required to actually be pointers to the same type,
245 and the final parameter must be a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>.
246 Finally, the version of <code class="computeroutput"><span class="identifier">copy</span></code>
247 calls <code class="computeroutput"><span class="identifier">do_copy</span></code>, passing <code class="computeroutput"><a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a><span class="special">&lt;</span><span class="identifier">value_type</span><span class="special">&gt;()</span></code> as the final parameter: this will dispatch
248 to the optimized version where appropriate, otherwise it will call the "slow
249 but safe version".
250 </p>
251 <h5>
252 <a name="boost_typetraits.background.h3"></a>
253 <span class="phrase"><a name="boost_typetraits.background.was_it_worth_it_"></a></span><a class="link" href="background.html#boost_typetraits.background.was_it_worth_it_">Was
254 it worth it?</a>
255 </h5>
256 <p>
257 It has often been repeated in these columns that "premature optimization
258 is the root of all evil" <a class="link" href="background.html#background.references">[4]</a>.
259 So the question must be asked: was our optimization premature? To put this
260 in perspective the timings for our version of copy compared a conventional
261 generic copy<a class="link" href="background.html#background.references">[5]</a> are shown in table
262 1.
263 </p>
264 <p>
265 Clearly the optimization makes a difference in this case; but, to be fair,
266 the timings are loaded to exclude cache miss effects - without this accurate
267 comparison between algorithms becomes difficult. However, perhaps we can add
268 a couple of caveats to the premature optimization rule:
269 </p>
270 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
271 <li class="listitem">
272 If you use the right algorithm for the job in the first place then optimization
273 will not be required; in some cases, memcpy is the right algorithm.
274 </li>
275 <li class="listitem">
276 If a component is going to be reused in many places by many people then
277 optimizations may well be worthwhile where they would not be so for a single
278 case - in other words, the likelihood that the optimization will be absolutely
279 necessary somewhere, sometime is that much higher. Just as importantly
280 the perceived value of the stock implementation will be higher: there is
281 no point standardizing an algorithm if users reject it on the grounds that
282 there are better, more heavily optimized versions available.
283 </li>
284 </ul></div>
285 <div class="table">
286 <a name="boost_typetraits.background.time_taken_to_copy_1000_elements_using__copy_const_t___t_____times_in_micro_seconds_"></a><p class="title"><b>Table&#160;1.1.&#160;Time taken to copy 1000 elements using `copy&lt;const T*, T*&gt;` (times
287 in micro-seconds)</b></p>
288 <div class="table-contents"><table class="table" summary="Time taken to copy 1000 elements using `copy&lt;const T*, T*&gt;` (times
289 in micro-seconds)">
290 <colgroup>
291 <col>
292 <col>
293 <col>
294 </colgroup>
295 <thead><tr>
296 <th>
297 <p>
298 Version
299 </p>
300 </th>
301 <th>
302 <p>
303 T
304 </p>
305 </th>
306 <th>
307 <p>
308 Time
309 </p>
310 </th>
311 </tr></thead>
312 <tbody>
313 <tr>
314 <td>
315 <p>
316 "Optimized" copy
317 </p>
318 </td>
319 <td>
320 <p>
321 char
322 </p>
323 </td>
324 <td>
325 <p>
326 0.99
327 </p>
328 </td>
329 </tr>
330 <tr>
331 <td>
332 <p>
333 Conventional copy
334 </p>
335 </td>
336 <td>
337 <p>
338 char
339 </p>
340 </td>
341 <td>
342 <p>
343 8.07
344 </p>
345 </td>
346 </tr>
347 <tr>
348 <td>
349 <p>
350 "Optimized" copy
351 </p>
352 </td>
353 <td>
354 <p>
355 int
356 </p>
357 </td>
358 <td>
359 <p>
360 2.52
361 </p>
362 </td>
363 </tr>
364 <tr>
365 <td>
366 <p>
367 Conventional copy
368 </p>
369 </td>
370 <td>
371 <p>
372 int
373 </p>
374 </td>
375 <td>
376 <p>
377 8.02
378 </p>
379 </td>
380 </tr>
381 </tbody>
382 </table></div>
383 </div>
384 <br class="table-break"><h5>
385 <a name="boost_typetraits.background.h4"></a>
386 <span class="phrase"><a name="boost_typetraits.background.pair_of_references"></a></span><a class="link" href="background.html#boost_typetraits.background.pair_of_references">Pair
387 of References</a>
388 </h5>
389 <p>
390 The optimized copy example shows how type traits may be used to perform optimization
391 decisions at compile-time. Another important usage of type traits is to allow
392 code to compile that otherwise would not do so unless excessive partial specialization
393 is used. This is possible by delegating partial specialization to the type
394 traits classes. Our example for this form of usage is a pair that can hold
395 references <a class="link" href="background.html#background.references">[6]</a>.
396 </p>
397 <p>
398 First, let us examine the definition of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>, omitting
399 the comparison operators, default constructor, and template copy constructor
400 for simplicity:
401 </p>
402 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
403 <span class="keyword">struct</span> <span class="identifier">pair</span>
404 <span class="special">{</span>
405 <span class="keyword">typedef</span> <span class="identifier">T1</span> <span class="identifier">first_type</span><span class="special">;</span>
406 <span class="keyword">typedef</span> <span class="identifier">T2</span> <span class="identifier">second_type</span><span class="special">;</span>
407
408 <span class="identifier">T1</span> <span class="identifier">first</span><span class="special">;</span>
409 <span class="identifier">T2</span> <span class="identifier">second</span><span class="special">;</span>
410
411 <span class="identifier">pair</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T1</span> <span class="special">&amp;</span> <span class="identifier">nfirst</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T2</span> <span class="special">&amp;</span> <span class="identifier">nsecond</span><span class="special">)</span>
412 <span class="special">:</span><span class="identifier">first</span><span class="special">(</span><span class="identifier">nfirst</span><span class="special">),</span> <span class="identifier">second</span><span class="special">(</span><span class="identifier">nsecond</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
413 <span class="special">};</span>
414 </pre>
415 <p>
416 Now, this "pair" cannot hold references as it currently stands, because
417 the constructor would require taking a reference to a reference, which is currently
418 illegal <a class="link" href="background.html#background.references">[7]</a>. Let us consider what
419 the constructor's parameters would have to be in order to allow "pair"
420 to hold non-reference types, references, and constant references:
421 </p>
422 <div class="table">
423 <a name="boost_typetraits.background.required_constructor_argument_types"></a><p class="title"><b>Table&#160;1.2.&#160;Required Constructor Argument Types</b></p>
424 <div class="table-contents"><table class="table" summary="Required Constructor Argument Types">
425 <colgroup>
426 <col>
427 <col>
428 </colgroup>
429 <thead><tr>
430 <th>
431 <p>
432 Type of <code class="computeroutput"><span class="identifier">T1</span></code>
433 </p>
434 </th>
435 <th>
436 <p>
437 Type of parameter to initializing constructor
438 </p>
439 </th>
440 </tr></thead>
441 <tbody>
442 <tr>
443 <td>
444 <p>
445 T
446 </p>
447 </td>
448 <td>
449 <p>
450 const T &amp;
451 </p>
452 </td>
453 </tr>
454 <tr>
455 <td>
456 <p>
457 T &amp;
458 </p>
459 </td>
460 <td>
461 <p>
462 T &amp;
463 </p>
464 </td>
465 </tr>
466 <tr>
467 <td>
468 <p>
469 const T &amp;
470 </p>
471 </td>
472 <td>
473 <p>
474 const T &amp;
475 </p>
476 </td>
477 </tr>
478 </tbody>
479 </table></div>
480 </div>
481 <br class="table-break"><p>
482 A little familiarity with the type traits classes allows us to construct a
483 single mapping that allows us to determine the type of parameter from the type
484 of the contained class. The type traits classes provide a transformation <a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a>, which
485 adds a reference to its type, unless it is already a reference.
486 </p>
487 <div class="table">
488 <a name="boost_typetraits.background.using_add_reference_to_synthesize_the_correct_constructor_type"></a><p class="title"><b>Table&#160;1.3.&#160;Using add_reference to synthesize the correct constructor type</b></p>
489 <div class="table-contents"><table class="table" summary="Using add_reference to synthesize the correct constructor type">
490 <colgroup>
491 <col>
492 <col>
493 <col>
494 </colgroup>
495 <thead><tr>
496 <th>
497 <p>
498 Type of <code class="computeroutput"><span class="identifier">T1</span></code>
499 </p>
500 </th>
501 <th>
502 <p>
503 Type of <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">T1</span></code>
504 </p>
505 </th>
506 <th>
507 <p>
508 Type of <code class="computeroutput"><span class="identifier">add_reference</span><span class="special">&lt;</span><span class="keyword">const</span>
509 <span class="identifier">T1</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
510 </p>
511 </th>
512 </tr></thead>
513 <tbody>
514 <tr>
515 <td>
516 <p>
517 T
518 </p>
519 </td>
520 <td>
521 <p>
522 const T
523 </p>
524 </td>
525 <td>
526 <p>
527 const T &amp;
528 </p>
529 </td>
530 </tr>
531 <tr>
532 <td>
533 <p>
534 T &amp;
535 </p>
536 </td>
537 <td>
538 <p>
539 T &amp; [8]
540 </p>
541 </td>
542 <td>
543 <p>
544 T &amp;
545 </p>
546 </td>
547 </tr>
548 <tr>
549 <td>
550 <p>
551 const T &amp;
552 </p>
553 </td>
554 <td>
555 <p>
556 const T &amp;
557 </p>
558 </td>
559 <td>
560 <p>
561 const T &amp;
562 </p>
563 </td>
564 </tr>
565 </tbody>
566 </table></div>
567 </div>
568 <br class="table-break"><p>
569 This allows us to build a primary template definition for <code class="computeroutput"><span class="identifier">pair</span></code>
570 that can contain non-reference types, reference types, and constant reference
571 types:
572 </p>
573 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
574 <span class="keyword">struct</span> <span class="identifier">pair</span>
575 <span class="special">{</span>
576 <span class="keyword">typedef</span> <span class="identifier">T1</span> <span class="identifier">first_type</span><span class="special">;</span>
577 <span class="keyword">typedef</span> <span class="identifier">T2</span> <span class="identifier">second_type</span><span class="special">;</span>
578
579 <span class="identifier">T1</span> <span class="identifier">first</span><span class="special">;</span>
580 <span class="identifier">T2</span> <span class="identifier">second</span><span class="special">;</span>
581
582 <span class="identifier">pair</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T1</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nfirst</span><span class="special">,</span>
583 <span class="identifier">boost</span><span class="special">::</span><a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T2</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nsecond</span><span class="special">)</span>
584 <span class="special">:</span><span class="identifier">first</span><span class="special">(</span><span class="identifier">nfirst</span><span class="special">),</span> <span class="identifier">second</span><span class="special">(</span><span class="identifier">nsecond</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
585 <span class="special">};</span>
586 </pre>
587 <p>
588 Add back in the standard comparison operators, default constructor, and template
589 copy constructor (which are all the same), and you have a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code> that
590 can hold reference types!
591 </p>
592 <p>
593 This same extension could have been done using partial template specialization
594 of <code class="computeroutput"><span class="identifier">pair</span></code>, but to specialize
595 <code class="computeroutput"><span class="identifier">pair</span></code> in this way would require
596 three partial specializations, plus the primary template. Type traits allows
597 us to define a single primary template that adjusts itself auto-magically to
598 any of these partial specializations, instead of a brute-force partial specialization
599 approach. Using type traits in this fashion allows programmers to delegate
600 partial specialization to the type traits classes, resulting in code that is
601 easier to maintain and easier to understand.
602 </p>
603 <h5>
604 <a name="boost_typetraits.background.h5"></a>
605 <span class="phrase"><a name="boost_typetraits.background.conclusion"></a></span><a class="link" href="background.html#boost_typetraits.background.conclusion">Conclusion</a>
606 </h5>
607 <p>
608 We hope that in this article we have been able to give you some idea of what
609 type-traits are all about. A more complete listing of the available classes
610 are in the boost documentation, along with further examples using type traits.
611 Templates have enabled C++ uses to take the advantage of the code reuse that
612 generic programming brings; hopefully this article has shown that generic programming
613 does not have to sink to the lowest common denominator, and that templates
614 can be optimal as well as generic.
615 </p>
616 <h5>
617 <a name="boost_typetraits.background.h6"></a>
618 <span class="phrase"><a name="boost_typetraits.background.acknowledgements"></a></span><a class="link" href="background.html#boost_typetraits.background.acknowledgements">Acknowledgements</a>
619 </h5>
620 <p>
621 The authors would like to thank Beman Dawes and Howard Hinnant for their helpful
622 comments when preparing this article.
623 </p>
624 <h5>
625 <a name="boost_typetraits.background.h7"></a>
626 <span class="phrase"><a name="boost_typetraits.background._anchor_id__background_references___references"></a></span><a class="link" href="background.html#boost_typetraits.background._anchor_id__background_references___references">References</a>
627 </h5>
628 <div class="orderedlist"><ol class="orderedlist" type="1">
629 <li class="listitem">
630 Nathan C. Myers, C++ Report, June 1995.
631 </li>
632 <li class="listitem">
633 The type traits library is based upon contributions by Steve Cleary, Beman
634 Dawes, Howard Hinnant and John Maddock: it can be found at www.boost.org.
635 </li>
636 <li class="listitem">
637 A scalar type is an arithmetic type (i.e. a built-in integer or floating
638 point type), an enumeration type, a pointer, a pointer to member, or a
639 const- or volatile-qualified version of one of these types.
640 </li>
641 <li class="listitem">
642 This quote is from Donald Knuth, ACM Computing Surveys, December 1974,
643 pg 268.
644 </li>
645 <li class="listitem">
646 The test code is available as part of the boost utility library (see algo_opt_examples.cpp),
647 the code was compiled with gcc 2.95 with all optimisations turned on, tests
648 were conducted on a 400MHz Pentium II machine running Microsoft Windows
649 98.
650 </li>
651 <li class="listitem">
652 John Maddock and Howard Hinnant have submitted a "compressed_pair"
653 library to Boost, which uses a technique similar to the one described here
654 to hold references. Their pair also uses type traits to determine if any
655 of the types are empty, and will derive instead of contain to conserve
656 space -- hence the name "compressed".
657 </li>
658 <li class="listitem">
659 This is actually an issue with the C++ Core Language Working Group (issue
660 #106), submitted by Bjarne Stroustrup. The tentative resolution is to allow
661 a "reference to a reference to T" to mean the same thing as a
662 "reference to T", but only in template instantiation, in a method
663 similar to multiple cv-qualifiers.
664 </li>
665 <li class="listitem">
666 For those of you who are wondering why this shouldn't be const-qualified,
667 remember that references are always implicitly constant (for example, you
668 can't re-assign a reference). Remember also that "const T &amp;"
669 is something completely different. For this reason, cv-qualifiers on template
670 type arguments that are references are ignored.
671 </li>
672 </ol></div>
673 </div>
674 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
675 <td align="left"></td>
676 <td align="right"><div class="copyright-footer">Copyright &#169; 2000, 2011 Adobe Systems Inc, David Abrahams,
677 Frederic Bron, Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant,
678 Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Alexander Nasonov, Thorsten
679 Ottosen, Roman Perepelitsa, Robert Ramey, Jeremy Siek, Robert Stewart and Steven
680 Watanabe<p>
681 Distributed under the Boost Software License, Version 1.0. (See accompanying
682 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>)
683 </p>
684 </div></td>
685 </tr></table>
686 <hr>
687 <div class="spirit-nav">
688 <a accesskey="p" href="intro.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="category.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
689 </div>
690 </body>
691 </html>