]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/utility/call_traits.htm
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / utility / call_traits.htm
1 <html>
2
3 <head>
4 <meta http-equiv="Content-Type"
5 content="text/html; charset=iso-8859-1">
6 <meta name="Template"
7 content="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"
13 vlink="#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
19 defined 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
23 from a function, and consists of a collection of typedefs defined
24 as in the table below. The purpose of call_traits is to ensure
25 that problems like &quot;<a href="#refs">references to references</a>&quot;
26 never occur, and that parameters are passed in the most efficient
27 manner possible (see <a href="#examples">examples</a>). In each
28 case if your existing practice is to use the type defined on the
29 left, then replace it with the call_traits defined type on the
30 right. </p>
31
32 <p>Note that for compilers that do not support either partial
33 specialization or member templates, no benefit will occur from
34 using call_traits: the call_traits defined types will always be
35 the same as the existing practice in this case. In addition if
36 only member templates and not partial template specialisation is
37 support by the compiler (for example Visual C++ 6) then
38 call_traits can not be used with array types (although it can be
39 used 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
138 be copy-constructed from which other types, those entries marked
139 with 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
236 possible:</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
335 various types, the table assumes that the compiler supports
336 partial specialization: if it doesn't then all types behave in
337 the same way as the entry for &quot;myclass&quot;, and
338 call_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
496 by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
497 file), the aim is to illustrate how each of the available
498 call_traits typedefs may be used:</p>
499
500 <pre>template &lt;class T&gt;
501 struct 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
528 problem):</h4>
529
530 <p>Consider the definition of std::binder1st:</p>
531
532 <pre>template &lt;class Operation&gt;
533 class binder1st :
534 public unary_function&lt;typename Operation::second_argument_type, typename Operation::result_type&gt;
535 {
536 protected:
537 Operation op;
538 typename Operation::first_argument_type value;
539 public:
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
545 the functor takes its second argument as a reference, that
546 implies that <code>Operation::second_argument_type</code> is a
547 reference type, <code>operator()</code> will now end up taking a
548 reference to a reference as an argument, and that is not
549 currently legal. The solution here is to modify <code>operator()</code>
550 to 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>
555 is a reference type, the argument is passed as a reference, and
556 the 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>,
561 then template argument deduction deduces the passed parameter as
562 &quot;const reference to array of T&quot;, this also applies to
563 string literals (which are really array literals). Consequently
564 instead of returning a pair of pointers, it tries to return a
565 pair of arrays, and since an array type is not copy-constructible
566 the code fails to compile. One solution is to explicitly cast the
567 arguments to make_pair to pointers, but call_traits provides a
568 better (i.e. automatic) solution (and one that works safely even
569 in generic code where the cast might do the wrong thing):</p>
570
571 <pre>template &lt;class T1, class T2&gt;
572 std::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
583 degraded to pointers if the deduced types are arrays, similar
584 situations occur in the standard binders and adapters: in
585 principle in any function that &quot;wraps&quot; a temporary
586 whose type is deduced. Note that the function arguments to
587 make_pair are not expressed in terms of call_traits: doing so
588 would 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
593 of a small built-in type as a function parameter, this mainly has
594 an effect when the parameter is used within a loop body. In the
595 following example (see <a
596 href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
597 a version of std::fill is optimized in two ways: if the type
598 passed is a single byte built-in type then std::memset is used to
599 effect the fill, otherwise a conventional C++ implemention is
600 used, but with the passed parameter &quot;optimized&quot; using
601 call_traits:</p>
602
603 <pre>namespace detail{
604
605 template &lt;bool opt&gt;
606 struct 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
619 template &lt;&gt;
620 struct 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
631 template &lt;class I, class T&gt;
632 inline 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
642 small built-in types is that with the value passed as &quot;T
643 const&quot; instead of &quot;const T&amp;&quot; the compiler is
644 able to tell both that the value is constant and that it is free
645 of aliases. With this information the compiler is able to cache
646 the passed value in a register, unroll the loop, or use
647 explicitly parallel instructions: if any of these are supported.
648 Exactly how much mileage you will get from this depends upon your
649 compiler - we could really use some accurate benchmarking
650 software as part of boost for cases like this.</p>
651
652 <p>Note that the function arguments to fill are not expressed in
653 terms of call_traits: doing so would prevent template argument
654 deduction from functioning. Instead fill acts as a &quot;thin
655 wrapper&quot; that is there to perform template argument
656 deduction, the compiler will optimise away the call to fill all
657 together, replacing it with the call to filler&lt;&gt;::do_fill,
658 which does use call_traits.</p>
659
660 <h3>Rationale</h3>
661
662 <p>The following notes are intended to briefly describe the
663 rational behind choices made in call_traits.</p>
664
665 <p>All user-defined types follow &quot;existing practice&quot;
666 and need no comment.</p>
667
668 <p>Small built-in types (what the standard calls fundamental
669 types [3.9.1]) differ from existing practice only in the <i>param_type</i>
670 typedef. In this case passing &quot;T const&quot; is compatible
671 with existing practice, but may improve performance in some cases
672 (see <a href="#ex4">Example 4</a>), in any case this should never
673 be 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
678 2</a> - references to references are not allowed, so the
679 call_traits members must be defined such that these problems do
680 not occur. There is a proposal to modify the language such that
681 &quot;a reference to a reference is a reference&quot; (issue #106,
682 submitted by Bjarne Stroustrup), call_traits&lt;T&gt;::value_type
683 and call_traits&lt;T&gt;::param_type both provide the same effect
684 as that proposal, without the need for a language change (in
685 other words it's a workaround).</p>
686
687 <p>For array types, a function that takes an array as an argument
688 will degrade the array type to a pointer type: this means that
689 the type of the actual parameter is different from its declared
690 type, something that can cause endless problems in template code
691 that relies on the declared type of a parameter. For example:</p>
692
693 <pre>template &lt;class T&gt;
694 struct A
695 {
696 void foo(T t);
697 };</pre>
698
699 <p><font face="Times New Roman">In this case if we instantiate
700 A&lt;int[2]&gt; then the declared type of the parameter passed to
701 member function foo is int[2], but it's actual type is const int*,
702 if we try to use the type T within the function body, then there
703 is a strong likelyhood that our code will not compile:</font></p>
704
705 <pre>template &lt;class T&gt;
706 void 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
712 explicit, and the type of the parameter is the same as it's
713 declared type:</p>
714
715 <pre>template &lt;class T&gt;
716 struct A
717 {
718 void foo(typename call_traits&lt;T&gt;::value_type t);
719 };
720
721 template &lt;class T&gt;
722 void 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
728 returned, not a copy of the whole array, and again call_traits
729 makes the degradation explicit. The value_type member is useful
730 whenever an array must be explicitly degraded to a pointer - <a
731 href="#ex3">Example 3</a> provides the test case (Footnote: the
732 array specialisation for call_traits is the least well understood
733 of all the call_traits specialisations, if the given semantics
734 cause specific problems for you, or don't solve a particular
735 array-related problem, then I would be interested to hear about
736 it. Most people though will probably never need to use this
737 specialisation).</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