Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/utility/call_traits.htm @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 27.5 KB
Line 
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
496by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
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>© Copyright boost.org 2000. Permission to copy, use, modify,
744sell and distribute this document is granted provided this
745copyright notice appears in all copies. This document is provided
746&quot;as is&quot; without express or implied warranty, and with
747no claim as to its suitability for any purpose.</p>
748
749<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
750Hinnant and John Maddock.</p>
751
752<p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John
753Maddock</a>, the latest version of this file can be found at <a
754href="http://www.boost.org/">www.boost.org</a>, and the boost
755discussion list at <a
756href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
757
758<p>.</p>
759
760<p>&nbsp;</p>
761
762<p>&nbsp;</p>
763</body>
764</html>
Note: See TracBrowser for help on using the repository browser.