]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/utility/call_traits.htm
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / utility / call_traits.htm
CommitLineData
7c673cae
FG
1<html>
2
3<head>
4<meta http-equiv="Content-Type"
5content="text/html; charset=iso-8859-1">
6<meta name="Template"
7content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
8<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
9<title>Call Traits</title>
10</head>
11
12<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
13vlink="#800080">
14
15<h1><img src="../../boost.png" width="276" height="86">Header
16&lt;<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>&gt;</h1>
17
18<p>All of the contents of &lt;boost/call_traits.hpp&gt; are
19defined inside namespace boost.</p>
20
21<p>The template class call_traits&lt;T&gt; encapsulates the
22&quot;best&quot; method to pass a parameter of some type T to or
23from a function, and consists of a collection of typedefs defined
24as in the table below. The purpose of call_traits is to ensure
25that problems like &quot;<a href="#refs">references to references</a>&quot;
26never occur, and that parameters are passed in the most efficient
27manner possible (see <a href="#examples">examples</a>). In each
28case if your existing practice is to use the type defined on the
29left, then replace it with the call_traits defined type on the
30right. </p>
31
32<p>Note that for compilers that do not support either partial
33specialization or member templates, no benefit will occur from
34using call_traits: the call_traits defined types will always be
35the same as the existing practice in this case. In addition if
36only member templates and not partial template specialisation is
37support by the compiler (for example Visual C++ 6) then
38call_traits can not be used with array types (although it can be
39used to solve the reference to reference problem).</p>
40
41<table border="0" cellpadding="7" cellspacing="1" width="797">
42 <tr>
43 <td valign="top" width="17%" bgcolor="#008080"><p
44 align="center">Existing practice</p>
45 </td>
46 <td valign="top" width="35%" bgcolor="#008080"><p
47 align="center">call_traits equivalent</p>
48 </td>
49 <td valign="top" width="32%" bgcolor="#008080"><p
50 align="center">Description</p>
51 </td>
52 <td valign="top" width="16%" bgcolor="#008080"><p
53 align="center">Notes</p>
54 </td>
55 </tr>
56 <tr>
57 <td valign="top" width="17%"><p align="center">T<br>
58 (return by value)</p>
59 </td>
60 <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::value_type</code></p>
61 </td>
62 <td valign="top" width="32%">Defines a type that
63 represents the &quot;value&quot; of type T. Use this for
64 functions that return by value, or possibly for stored
65 values of type T.</td>
66 <td valign="top" width="16%"><p align="center">2</p>
67 </td>
68 </tr>
69 <tr>
70 <td valign="top" width="17%"><p align="center">T&amp;<br>
71 (return value)</p>
72 </td>
73 <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::reference</code></p>
74 </td>
75 <td valign="top" width="32%">Defines a type that
76 represents a reference to type T. Use for functions that
77 would normally return a T&amp;.</td>
78 <td valign="top" width="16%"><p align="center">1</p>
79 </td>
80 </tr>
81 <tr>
82 <td valign="top" width="17%"><p align="center">const
83 T&amp;<br>
84 (return value)</p>
85 </td>
86 <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::const_reference</code></p>
87 </td>
88 <td valign="top" width="32%">Defines a type that
89 represents a constant reference to type T. Use for
90 functions that would normally return a const T&amp;.</td>
91 <td valign="top" width="16%"><p align="center">1</p>
92 </td>
93 </tr>
94 <tr>
95 <td valign="top" width="17%"><p align="center">const
96 T&amp;<br>
97 (function parameter)</p>
98 </td>
99 <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::param_type</code></p>
100 </td>
101 <td valign="top" width="32%">Defines a type that
102 represents the &quot;best&quot; way to pass a parameter
103 of type T to a function.</td>
104 <td valign="top" width="16%"><p align="center">1,3</p>
105 </td>
106 </tr>
107</table>
108
109<p>Notes:</p>
110
111<ol>
112 <li>If T is already reference type, then call_traits is
113 defined such that <a href="#refs">references to
114 references</a> do not occur (requires partial
115 specialization).</li>
116 <li>If T is an array type, then call_traits defines <code>value_type</code>
117 as a &quot;constant pointer to type&quot; rather than an
118 &quot;array of type&quot; (requires partial
119 specialization). Note that if you are using value_type as
120 a stored value then this will result in storing a &quot;constant
121 pointer to an array&quot; rather than the array itself.
122 This may or may not be a good thing depending upon what
123 you actually need (in other words take care!).</li>
124 <li>If T is a small built in type or a pointer, then <code>param_type</code>
125 is defined as <code>T const</code>, instead of <code>T
126 const&amp;</code>. This can improve the ability of the
127 compiler to optimize loops in the body of the function if
128 they depend upon the passed parameter, the semantics of
129 the passed parameter is otherwise unchanged (requires
130 partial specialization).</li>
131</ol>
132
133<p>&nbsp;</p>
134
135<h3>Copy constructibility</h3>
136
137<p>The following table defines which call_traits types can always
138be copy-constructed from which other types, those entries marked
139with a '?' are true only if and only if T is copy constructible:</p>
140
141<table border="0" cellpadding="7" cellspacing="1" width="766">
142 <tr>
143 <td valign="top" width="17%">&nbsp;</td>
144 <td valign="top" colspan="5" width="85%"
145 bgcolor="#008080"><p align="center">To:</p>
146 </td>
147 </tr>
148 <tr>
149 <td valign="top" width="17%" bgcolor="#008080">From:</td>
150 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
151 align="center">T</p>
152 </td>
153 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
154 align="center">value_type</p>
155 </td>
156 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
157 align="center">reference</p>
158 </td>
159 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
160 align="center">const_reference</p>
161 </td>
162 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
163 align="center">param_type</p>
164 </td>
165 </tr>
166 <tr>
167 <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
168 <td valign="top" width="17%"><p align="center">?</p>
169 </td>
170 <td valign="top" width="17%"><p align="center">?</p>
171 </td>
172 <td valign="top" width="17%"><p align="center">Y</p>
173 </td>
174 <td valign="top" width="17%"><p align="center">Y</p>
175 </td>
176 <td valign="top" width="17%"><p align="center">Y</p>
177 </td>
178 </tr>
179 <tr>
180 <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
181 <td valign="top" width="17%"><p align="center">?</p>
182 </td>
183 <td valign="top" width="17%"><p align="center">?</p>
184 </td>
185 <td valign="top" width="17%"><p align="center">N</p>
186 </td>
187 <td valign="top" width="17%"><p align="center">N</p>
188 </td>
189 <td valign="top" width="17%"><p align="center">Y</p>
190 </td>
191 </tr>
192 <tr>
193 <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
194 <td valign="top" width="17%"><p align="center">?</p>
195 </td>
196 <td valign="top" width="17%"><p align="center">?</p>
197 </td>
198 <td valign="top" width="17%"><p align="center">Y</p>
199 </td>
200 <td valign="top" width="17%"><p align="center">Y</p>
201 </td>
202 <td valign="top" width="17%"><p align="center">Y</p>
203 </td>
204 </tr>
205 <tr>
206 <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
207 <td valign="top" width="17%"><p align="center">?</p>
208 </td>
209 <td valign="top" width="17%"><p align="center">N</p>
210 </td>
211 <td valign="top" width="17%"><p align="center">N</p>
212 </td>
213 <td valign="top" width="17%"><p align="center">Y</p>
214 </td>
215 <td valign="top" width="17%"><p align="center">Y</p>
216 </td>
217 </tr>
218 <tr>
219 <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
220 <td valign="top" width="17%"><p align="center">?</p>
221 </td>
222 <td valign="top" width="17%"><p align="center">?</p>
223 </td>
224 <td valign="top" width="17%"><p align="center">N</p>
225 </td>
226 <td valign="top" width="17%"><p align="center">N</p>
227 </td>
228 <td valign="top" width="17%"><p align="center">Y</p>
229 </td>
230 </tr>
231</table>
232
233<p>&nbsp;</p>
234
235<p>If T is an assignable type the following assignments are
236possible:</p>
237
238<table border="0" cellpadding="7" cellspacing="1" width="766">
239 <tr>
240 <td valign="top" width="17%">&nbsp;</td>
241 <td valign="top" colspan="5" width="85%"
242 bgcolor="#008080"><p align="center">To:</p>
243 </td>
244 </tr>
245 <tr>
246 <td valign="top" width="17%" bgcolor="#008080">From:</td>
247 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
248 align="center">T</p>
249 </td>
250 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
251 align="center">value_type</p>
252 </td>
253 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
254 align="center">reference</p>
255 </td>
256 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
257 align="center">const_reference</p>
258 </td>
259 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
260 align="center">param_type</p>
261 </td>
262 </tr>
263 <tr>
264 <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
265 <td valign="top" width="17%"><p align="center">Y</p>
266 </td>
267 <td valign="top" width="17%"><p align="center">Y</p>
268 </td>
269 <td valign="top" width="17%"><p align="center">-</p>
270 </td>
271 <td valign="top" width="17%"><p align="center">-</p>
272 </td>
273 <td valign="top" width="17%"><p align="center">-</p>
274 </td>
275 </tr>
276 <tr>
277 <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
278 <td valign="top" width="17%"><p align="center">Y</p>
279 </td>
280 <td valign="top" width="17%"><p align="center">Y</p>
281 </td>
282 <td valign="top" width="17%"><p align="center">-</p>
283 </td>
284 <td valign="top" width="17%"><p align="center">-</p>
285 </td>
286 <td valign="top" width="17%"><p align="center">-</p>
287 </td>
288 </tr>
289 <tr>
290 <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
291 <td valign="top" width="17%"><p align="center">Y</p>
292 </td>
293 <td valign="top" width="17%"><p align="center">Y</p>
294 </td>
295 <td valign="top" width="17%"><p align="center">-</p>
296 </td>
297 <td valign="top" width="17%"><p align="center">-</p>
298 </td>
299 <td valign="top" width="17%"><p align="center">-</p>
300 </td>
301 </tr>
302 <tr>
303 <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
304 <td valign="top" width="17%"><p align="center">Y</p>
305 </td>
306 <td valign="top" width="17%"><p align="center">Y</p>
307 </td>
308 <td valign="top" width="17%"><p align="center">-</p>
309 </td>
310 <td valign="top" width="17%"><p align="center">-</p>
311 </td>
312 <td valign="top" width="17%"><p align="center">-</p>
313 </td>
314 </tr>
315 <tr>
316 <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
317 <td valign="top" width="17%"><p align="center">Y</p>
318 </td>
319 <td valign="top" width="17%"><p align="center">Y</p>
320 </td>
321 <td valign="top" width="17%"><p align="center">-</p>
322 </td>
323 <td valign="top" width="17%"><p align="center">-</p>
324 </td>
325 <td valign="top" width="17%"><p align="center">-</p>
326 </td>
327 </tr>
328</table>
329
330<p>&nbsp;</p>
331
332<h3><a name="examples"></a>Examples</h3>
333
334<p>The following table shows the effect that call_traits has on
335various types, the table assumes that the compiler supports
336partial specialization: if it doesn't then all types behave in
337the same way as the entry for &quot;myclass&quot;, and
338call_traits can not be used with reference or array types.</p>
339
340<table border="0" cellpadding="7" cellspacing="1" width="766">
341 <tr>
342 <td valign="top" width="17%">&nbsp;</td>
343 <td valign="top" colspan="5" width="85%"
344 bgcolor="#008080"><p align="center">Call_traits type:</p>
345 </td>
346 </tr>
347 <tr>
348 <td valign="top" width="17%" bgcolor="#008080"><p
349 align="center">Original type T</p>
350 </td>
351 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
352 align="center">value_type</p>
353 </td>
354 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
355 align="center">reference</p>
356 </td>
357 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
358 align="center">const_reference</p>
359 </td>
360 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
361 align="center">param_type</p>
362 </td>
363 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
364 align="center">Applies to:</p>
365 </td>
366 </tr>
367 <tr>
368 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
369 align="center">myclass</p>
370 </td>
371 <td valign="top" width="17%"><p align="center">myclass</p>
372 </td>
373 <td valign="top" width="17%"><p align="center">myclass&amp;</p>
374 </td>
375 <td valign="top" width="17%"><p align="center">const
376 myclass&amp;</p>
377 </td>
378 <td valign="top" width="17%"><p align="center">myclass
379 const&amp;</p>
380 </td>
381 <td valign="top" width="17%"><p align="center">All user
382 defined types.</p>
383 </td>
384 </tr>
385 <tr>
386 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
387 align="center">int</p>
388 </td>
389 <td valign="top" width="17%"><p align="center">int</p>
390 </td>
391 <td valign="top" width="17%"><p align="center">int&amp;</p>
392 </td>
393 <td valign="top" width="17%"><p align="center">const
394 int&amp;</p>
395 </td>
396 <td valign="top" width="17%"><p align="center">int const</p>
397 </td>
398 <td valign="top" width="17%"><p align="center">All small
399 built-in types.</p>
400 </td>
401 </tr>
402 <tr>
403 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
404 align="center">int*</p>
405 </td>
406 <td valign="top" width="17%"><p align="center">int*</p>
407 </td>
408 <td valign="top" width="17%"><p align="center">int*&amp;</p>
409 </td>
410 <td valign="top" width="17%"><p align="center">int*const&amp;</p>
411 </td>
412 <td valign="top" width="17%"><p align="center">int* const</p>
413 </td>
414 <td valign="top" width="17%"><p align="center">All
415 pointer types.</p>
416 </td>
417 </tr>
418 <tr>
419 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
420 align="center">int&amp;</p>
421 </td>
422 <td valign="top" width="17%"><p align="center">int&amp;</p>
423 </td>
424 <td valign="top" width="17%"><p align="center">int&amp;</p>
425 </td>
426 <td valign="top" width="17%"><p align="center">const
427 int&amp;</p>
428 </td>
429 <td valign="top" width="17%"><p align="center">int&amp;</p>
430 </td>
431 <td valign="top" width="17%"><p align="center">All
432 reference types.</p>
433 </td>
434 </tr>
435 <tr>
436 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
437 align="center">const int&amp;</p>
438 </td>
439 <td valign="top" width="17%"><p align="center">const
440 int&amp;</p>
441 </td>
442 <td valign="top" width="17%"><p align="center">const
443 int&amp;</p>
444 </td>
445 <td valign="top" width="17%"><p align="center">const
446 int&amp;</p>
447 </td>
448 <td valign="top" width="17%"><p align="center">const
449 int&amp;</p>
450 </td>
451 <td valign="top" width="17%"><p align="center">All
452 constant-references.</p>
453 </td>
454 </tr>
455 <tr>
456 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
457 align="center">int[3]</p>
458 </td>
459 <td valign="top" width="17%"><p align="center">const int*</p>
460 </td>
461 <td valign="top" width="17%"><p align="center">int(&amp;)[3]</p>
462 </td>
463 <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
464 </td>
465 <td valign="top" width="17%"><p align="center">const int*
466 const</p>
467 </td>
468 <td valign="top" width="17%"><p align="center">All array
469 types.</p>
470 </td>
471 </tr>
472 <tr>
473 <td valign="top" width="17%" bgcolor="#C0C0C0"><p
474 align="center">const int[3]</p>
475 </td>
476 <td valign="top" width="17%"><p align="center">const int*</p>
477 </td>
478 <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
479 </td>
480 <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
481 </td>
482 <td valign="top" width="17%"><p align="center">const int*
483 const</p>
484 </td>
485 <td valign="top" width="17%"><p align="center">All
486 constant-array types.</p>
487 </td>
488 </tr>
489</table>
490
491<p>&nbsp;</p>
492
493<h4>Example 1:</h4>
494
495<p>The following class is a trivial class that stores some type T
92f5a8d4 496by value (see the <a href="test/call_traits_test.cpp">call_traits_test.cpp</a>
7c673cae
FG
497file), the aim is to illustrate how each of the available
498call_traits typedefs may be used:</p>
499
500<pre>template &lt;class T&gt;
501struct contained
502{
503 // define our typedefs first, arrays are stored by value
504 // so value_type is not the same as result_type:
505 typedef typename boost::call_traits&lt;T&gt;::param_type param_type;
506 typedef typename boost::call_traits&lt;T&gt;::reference reference;
507 typedef typename boost::call_traits&lt;T&gt;::const_reference const_reference;
508 typedef T value_type;
509 typedef typename boost::call_traits&lt;T&gt;::value_type result_type;
510
511 // stored value:
512 value_type v_;
513
514 // constructors:
515 contained() {}
516 contained(param_type p) : v_(p){}
517 // return byval:
518 result_type value() { return v_; }
519 // return by_ref:
520 reference get() { return v_; }
521 const_reference const_get()const { return v_; }
522 // pass value:
523 void call(param_type p){}
524
525};</pre>
526
527<h4><a name="refs"></a>Example 2 (the reference to reference
528problem):</h4>
529
530<p>Consider the definition of std::binder1st:</p>
531
532<pre>template &lt;class Operation&gt;
533class binder1st :
534 public unary_function&lt;typename Operation::second_argument_type, typename Operation::result_type&gt;
535{
536protected:
537 Operation op;
538 typename Operation::first_argument_type value;
539public:
540 binder1st(const Operation&amp; x, const typename Operation::first_argument_type&amp; y);
541 typename Operation::result_type operator()(const typename Operation::second_argument_type&amp; x) const;
542}; </pre>
543
544<p>Now consider what happens in the relatively common case that
545the functor takes its second argument as a reference, that
546implies that <code>Operation::second_argument_type</code> is a
547reference type, <code>operator()</code> will now end up taking a
548reference to a reference as an argument, and that is not
549currently legal. The solution here is to modify <code>operator()</code>
550to use call_traits:</p>
551
552<pre>typename Operation::result_type operator()(typename call_traits&lt;typename Operation::second_argument_type&gt;::param_type x) const;</pre>
553
554<p>Now in the case that <code>Operation::second_argument_type</code>
555is a reference type, the argument is passed as a reference, and
556the no &quot;reference to reference&quot; occurs.</p>
557
558<h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4>
559
560<p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>,
561then template argument deduction deduces the passed parameter as
562&quot;const reference to array of T&quot;, this also applies to
563string literals (which are really array literals). Consequently
564instead of returning a pair of pointers, it tries to return a
565pair of arrays, and since an array type is not copy-constructible
566the code fails to compile. One solution is to explicitly cast the
567arguments to make_pair to pointers, but call_traits provides a
568better (i.e. automatic) solution (and one that works safely even
569in generic code where the cast might do the wrong thing):</p>
570
571<pre>template &lt;class T1, class T2&gt;
572std::pair&lt;
573 typename boost::call_traits&lt;T1&gt;::value_type,
574 typename boost::call_traits&lt;T2&gt;::value_type&gt;
575 make_pair(const T1&amp; t1, const T2&amp; t2)
576{
577 return std::pair&lt;
578 typename boost::call_traits&lt;T1&gt;::value_type,
579 typename boost::call_traits&lt;T2&gt;::value_type&gt;(t1, t2);
580}</pre>
581
582<p>Here, the deduced argument types will be automatically
583degraded to pointers if the deduced types are arrays, similar
584situations occur in the standard binders and adapters: in
585principle in any function that &quot;wraps&quot; a temporary
586whose type is deduced. Note that the function arguments to
587make_pair are not expressed in terms of call_traits: doing so
588would prevent template argument deduction from functioning.</p>
589
590<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
591
592<p>The call_traits template will &quot;optimize&quot; the passing
593of a small built-in type as a function parameter, this mainly has
594an effect when the parameter is used within a loop body. In the
595following example (see <a
596href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
597a version of std::fill is optimized in two ways: if the type
598passed is a single byte built-in type then std::memset is used to
599effect the fill, otherwise a conventional C++ implemention is
600used, but with the passed parameter &quot;optimized&quot; using
601call_traits:</p>
602
603<pre>namespace detail{
604
605template &lt;bool opt&gt;
606struct filler
607{
608 template &lt;typename I, typename T&gt;
609 static void do_fill(I first, I last, typename boost::call_traits&lt;T&gt;::param_type val)
610 {
611 while(first != last)
612 {
613 *first = val;
614 ++first;
615 }
616 }
617};
618
619template &lt;&gt;
620struct filler&lt;true&gt;
621{
622 template &lt;typename I, typename T&gt;
623 static void do_fill(I first, I last, T val)
624 {
625 memset(first, val, last-first);
626 }
627};
628
629}
630
631template &lt;class I, class T&gt;
632inline void fill(I first, I last, const T&amp; val)
633{
634 enum{ can_opt = boost::is_pointer&lt;I&gt;::value
635 &amp;&amp; boost::is_arithmetic&lt;T&gt;::value
636 &amp;&amp; (sizeof(T) == 1) };
637 typedef detail::filler&lt;can_opt&gt; filler_t;
638 filler_t::template do_fill&lt;I,T&gt;(first, last, val);
639}</pre>
640
641<p>Footnote: the reason that this is &quot;optimal&quot; for
642small built-in types is that with the value passed as &quot;T
643const&quot; instead of &quot;const T&amp;&quot; the compiler is
644able to tell both that the value is constant and that it is free
645of aliases. With this information the compiler is able to cache
646the passed value in a register, unroll the loop, or use
647explicitly parallel instructions: if any of these are supported.
648Exactly how much mileage you will get from this depends upon your
649compiler - we could really use some accurate benchmarking
650software as part of boost for cases like this.</p>
651
652<p>Note that the function arguments to fill are not expressed in
653terms of call_traits: doing so would prevent template argument
654deduction from functioning. Instead fill acts as a &quot;thin
655wrapper&quot; that is there to perform template argument
656deduction, the compiler will optimise away the call to fill all
657together, replacing it with the call to filler&lt;&gt;::do_fill,
658which does use call_traits.</p>
659
660<h3>Rationale</h3>
661
662<p>The following notes are intended to briefly describe the
663rational behind choices made in call_traits.</p>
664
665<p>All user-defined types follow &quot;existing practice&quot;
666and need no comment.</p>
667
668<p>Small built-in types (what the standard calls fundamental
669types [3.9.1]) differ from existing practice only in the <i>param_type</i>
670typedef. In this case passing &quot;T const&quot; is compatible
671with existing practice, but may improve performance in some cases
672(see <a href="#ex4">Example 4</a>), in any case this should never
673be any worse than existing practice.</p>
674
675<p>Pointers follow the same rational as small built-in types.</p>
676
677<p>For reference types the rational follows <a href="#refs">Example
6782</a> - references to references are not allowed, so the
679call_traits members must be defined such that these problems do
680not occur. There is a proposal to modify the language such that
681&quot;a reference to a reference is a reference&quot; (issue #106,
682submitted by Bjarne Stroustrup), call_traits&lt;T&gt;::value_type
683and call_traits&lt;T&gt;::param_type both provide the same effect
684as that proposal, without the need for a language change (in
685other words it's a workaround).</p>
686
687<p>For array types, a function that takes an array as an argument
688will degrade the array type to a pointer type: this means that
689the type of the actual parameter is different from its declared
690type, something that can cause endless problems in template code
691that relies on the declared type of a parameter. For example:</p>
692
693<pre>template &lt;class T&gt;
694struct A
695{
696 void foo(T t);
697};</pre>
698
699<p><font face="Times New Roman">In this case if we instantiate
700A&lt;int[2]&gt; then the declared type of the parameter passed to
701member function foo is int[2], but it's actual type is const int*,
702if we try to use the type T within the function body, then there
703is a strong likelyhood that our code will not compile:</font></p>
704
705<pre>template &lt;class T&gt;
706void A&lt;T&gt;::foo(T t)
707{
708 T dup(t); // doesn't compile for case that T is an array.
709}</pre>
710
711<p>By using call_traits the degradation from array to pointer is
712explicit, and the type of the parameter is the same as it's
713declared type:</p>
714
715<pre>template &lt;class T&gt;
716struct A
717{
718 void foo(typename call_traits&lt;T&gt;::value_type t);
719};
720
721template &lt;class T&gt;
722void A&lt;T&gt;::foo(typename call_traits&lt;T&gt;::value_type t)
723{
724 typename call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
725}</pre>
726
727<p>For value_type (return by value), again only a pointer may be
728returned, not a copy of the whole array, and again call_traits
729makes the degradation explicit. The value_type member is useful
730whenever an array must be explicitly degraded to a pointer - <a
731href="#ex3">Example 3</a> provides the test case (Footnote: the
732array specialisation for call_traits is the least well understood
733of all the call_traits specialisations, if the given semantics
734cause specific problems for you, or don't solve a particular
735array-related problem, then I would be interested to hear about
736it. Most people though will probably never need to use this
737specialisation).</p>
738
739<hr>
740
741<p>Revised 01 September 2000</p>
742
743 <p>
744 Copyright 2000 Steve Cleary, Beman Dawes, Howard
745 Hinnant and John Maddock. <br/>
746 Use, modification and distribution are subject to the
747 Boost Software License, Version 1.0.
748 (See accompanying file LICENSE_1_0.txt
749 or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
750 http://www.boost.org/LICENSE_1_0.txt
751 </a>).
752 </p>
753</body>
754</html>
755