4 <meta http-equiv=
"Content-Type"
5 content=
"text/html; charset=iso-8859-1">
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>
12 <body bgcolor=
"#FFFFFF" text=
"#000000" link=
"#0000FF"
15 <h1><img src=
"../../boost.png" width=
"276" height=
"86">Header
16 <<a href=
"../../boost/detail/call_traits.hpp">boost/call_traits.hpp
</a>></h1>
18 <p>All of the contents of
<boost/call_traits.hpp
> are
19 defined inside namespace boost.
</p>
21 <p>The template class call_traits
<T
> encapsulates the
22 "best
" 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
"<a href=
"#refs">references to references
</a>"
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
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>
41 <table border=
"0" cellpadding=
"7" cellspacing=
"1" width=
"797">
43 <td valign=
"top" width=
"17%" bgcolor=
"#008080"><p
44 align=
"center">Existing practice
</p>
46 <td valign=
"top" width=
"35%" bgcolor=
"#008080"><p
47 align=
"center">call_traits equivalent
</p>
49 <td valign=
"top" width=
"32%" bgcolor=
"#008080"><p
50 align=
"center">Description
</p>
52 <td valign=
"top" width=
"16%" bgcolor=
"#008080"><p
53 align=
"center">Notes
</p>
57 <td valign=
"top" width=
"17%"><p align=
"center">T
<br>
60 <td valign=
"top" width=
"35%"><p align=
"center"><code>call_traits
<T
>::value_type
</code></p>
62 <td valign=
"top" width=
"32%">Defines a type that
63 represents the
"value
" 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>
70 <td valign=
"top" width=
"17%"><p align=
"center">T
&<br>
73 <td valign=
"top" width=
"35%"><p align=
"center"><code>call_traits
<T
>::reference
</code></p>
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
&.
</td>
78 <td valign=
"top" width=
"16%"><p align=
"center">1</p>
82 <td valign=
"top" width=
"17%"><p align=
"center">const
86 <td valign=
"top" width=
"35%"><p align=
"center"><code>call_traits
<T
>::const_reference
</code></p>
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
&.
</td>
91 <td valign=
"top" width=
"16%"><p align=
"center">1</p>
95 <td valign=
"top" width=
"17%"><p align=
"center">const
97 (function parameter)
</p>
99 <td valign=
"top" width=
"35%"><p align=
"center"><code>call_traits
<T
>::param_type
</code></p>
101 <td valign=
"top" width=
"32%">Defines a type that
102 represents the
"best
" 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>
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
"constant pointer to type
" rather than an
118 "array of type
" (requires partial
119 specialization). Note that if you are using value_type as
120 a stored value then this will result in storing a
"constant
121 pointer to an array
" 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
&</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>
135 <h3>Copy constructibility
</h3>
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>
141 <table border=
"0" cellpadding=
"7" cellspacing=
"1" width=
"766">
143 <td valign=
"top" width=
"17%"> </td>
144 <td valign=
"top" colspan=
"5" width=
"85%"
145 bgcolor=
"#008080"><p align=
"center">To:
</p>
149 <td valign=
"top" width=
"17%" bgcolor=
"#008080">From:
</td>
150 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
153 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
154 align=
"center">value_type
</p>
156 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
157 align=
"center">reference
</p>
159 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
160 align=
"center">const_reference
</p>
162 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
163 align=
"center">param_type
</p>
167 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">T
</td>
168 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
170 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
172 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
174 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
176 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
180 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">value_type
</td>
181 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
183 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
185 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
187 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
189 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
193 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">reference
</td>
194 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
196 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
198 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
200 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
202 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
206 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">const_reference
</td>
207 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
209 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
211 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
213 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
215 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
219 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">param_type
</td>
220 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
222 <td valign=
"top" width=
"17%"><p align=
"center">?
</p>
224 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
226 <td valign=
"top" width=
"17%"><p align=
"center">N
</p>
228 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
235 <p>If T is an assignable type the following assignments are
238 <table border=
"0" cellpadding=
"7" cellspacing=
"1" width=
"766">
240 <td valign=
"top" width=
"17%"> </td>
241 <td valign=
"top" colspan=
"5" width=
"85%"
242 bgcolor=
"#008080"><p align=
"center">To:
</p>
246 <td valign=
"top" width=
"17%" bgcolor=
"#008080">From:
</td>
247 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
250 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
251 align=
"center">value_type
</p>
253 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
254 align=
"center">reference
</p>
256 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
257 align=
"center">const_reference
</p>
259 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
260 align=
"center">param_type
</p>
264 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">T
</td>
265 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
267 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
269 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
271 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
273 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
277 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">value_type
</td>
278 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
280 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
282 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
284 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
286 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
290 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">reference
</td>
291 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
293 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
295 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
297 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
299 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
303 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">const_reference
</td>
304 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
306 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
308 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
310 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
312 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
316 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0">param_type
</td>
317 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
319 <td valign=
"top" width=
"17%"><p align=
"center">Y
</p>
321 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
323 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
325 <td valign=
"top" width=
"17%"><p align=
"center">-
</p>
332 <h3><a name=
"examples"></a>Examples
</h3>
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
"myclass
", and
338 call_traits can not be used with reference or array types.
</p>
340 <table border=
"0" cellpadding=
"7" cellspacing=
"1" width=
"766">
342 <td valign=
"top" width=
"17%"> </td>
343 <td valign=
"top" colspan=
"5" width=
"85%"
344 bgcolor=
"#008080"><p align=
"center">Call_traits type:
</p>
348 <td valign=
"top" width=
"17%" bgcolor=
"#008080"><p
349 align=
"center">Original type T
</p>
351 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
352 align=
"center">value_type
</p>
354 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
355 align=
"center">reference
</p>
357 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
358 align=
"center">const_reference
</p>
360 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
361 align=
"center">param_type
</p>
363 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
364 align=
"center">Applies to:
</p>
368 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
369 align=
"center">myclass
</p>
371 <td valign=
"top" width=
"17%"><p align=
"center">myclass
</p>
373 <td valign=
"top" width=
"17%"><p align=
"center">myclass
&</p>
375 <td valign=
"top" width=
"17%"><p align=
"center">const
378 <td valign=
"top" width=
"17%"><p align=
"center">myclass
381 <td valign=
"top" width=
"17%"><p align=
"center">All user
386 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
387 align=
"center">int
</p>
389 <td valign=
"top" width=
"17%"><p align=
"center">int
</p>
391 <td valign=
"top" width=
"17%"><p align=
"center">int
&</p>
393 <td valign=
"top" width=
"17%"><p align=
"center">const
396 <td valign=
"top" width=
"17%"><p align=
"center">int const
</p>
398 <td valign=
"top" width=
"17%"><p align=
"center">All small
403 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
404 align=
"center">int*
</p>
406 <td valign=
"top" width=
"17%"><p align=
"center">int*
</p>
408 <td valign=
"top" width=
"17%"><p align=
"center">int*
&</p>
410 <td valign=
"top" width=
"17%"><p align=
"center">int*const
&</p>
412 <td valign=
"top" width=
"17%"><p align=
"center">int* const
</p>
414 <td valign=
"top" width=
"17%"><p align=
"center">All
419 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
420 align=
"center">int
&</p>
422 <td valign=
"top" width=
"17%"><p align=
"center">int
&</p>
424 <td valign=
"top" width=
"17%"><p align=
"center">int
&</p>
426 <td valign=
"top" width=
"17%"><p align=
"center">const
429 <td valign=
"top" width=
"17%"><p align=
"center">int
&</p>
431 <td valign=
"top" width=
"17%"><p align=
"center">All
436 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
437 align=
"center">const int
&</p>
439 <td valign=
"top" width=
"17%"><p align=
"center">const
442 <td valign=
"top" width=
"17%"><p align=
"center">const
445 <td valign=
"top" width=
"17%"><p align=
"center">const
448 <td valign=
"top" width=
"17%"><p align=
"center">const
451 <td valign=
"top" width=
"17%"><p align=
"center">All
452 constant-references.
</p>
456 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
457 align=
"center">int[
3]
</p>
459 <td valign=
"top" width=
"17%"><p align=
"center">const int*
</p>
461 <td valign=
"top" width=
"17%"><p align=
"center">int(
&)[
3]
</p>
463 <td valign=
"top" width=
"17%"><p align=
"center">const int(
&)[
3]
</p>
465 <td valign=
"top" width=
"17%"><p align=
"center">const int*
468 <td valign=
"top" width=
"17%"><p align=
"center">All array
473 <td valign=
"top" width=
"17%" bgcolor=
"#C0C0C0"><p
474 align=
"center">const int[
3]
</p>
476 <td valign=
"top" width=
"17%"><p align=
"center">const int*
</p>
478 <td valign=
"top" width=
"17%"><p align=
"center">const int(
&)[
3]
</p>
480 <td valign=
"top" width=
"17%"><p align=
"center">const int(
&)[
3]
</p>
482 <td valign=
"top" width=
"17%"><p align=
"center">const int*
485 <td valign=
"top" width=
"17%"><p align=
"center">All
486 constant-array types.
</p>
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>
500 <pre>template
<class T
>
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
<T
>::param_type param_type;
506 typedef typename boost::call_traits
<T
>::reference reference;
507 typedef typename boost::call_traits
<T
>::const_reference const_reference;
508 typedef T value_type;
509 typedef typename boost::call_traits
<T
>::value_type result_type;
516 contained(param_type p) : v_(p){}
518 result_type value() { return v_; }
520 reference get() { return v_; }
521 const_reference const_get()const { return v_; }
523 void call(param_type p){}
527 <h4><a name=
"refs"></a>Example
2 (the reference to reference
530 <p>Consider the definition of std::binder1st:
</p>
532 <pre>template
<class Operation
>
534 public unary_function
<typename Operation::second_argument_type, typename Operation::result_type
>
538 typename Operation::first_argument_type value;
540 binder1st(const Operation
& x, const typename Operation::first_argument_type
& y);
541 typename Operation::result_type operator()(const typename Operation::second_argument_type
& x) const;
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>
552 <pre>typename Operation::result_type operator()(typename call_traits
<typename Operation::second_argument_type
>::param_type x) const;
</pre>
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
"reference to reference
" occurs.
</p>
558 <h4><a name=
"ex3"></a>Example
3 (the make_pair problem):
</h4>
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 "const reference to array of T
", 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>
571 <pre>template
<class T1, class T2
>
573 typename boost::call_traits
<T1
>::value_type,
574 typename boost::call_traits
<T2
>::value_type
>
575 make_pair(const T1
& t1, const T2
& t2)
578 typename boost::call_traits
<T1
>::value_type,
579 typename boost::call_traits
<T2
>::value_type
>(t1, t2);
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
"wraps
" 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>
590 <h4><a name=
"ex4"></a>Example
4 (optimising fill):
</h4>
592 <p>The call_traits template will
"optimize
" 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
"optimized
" using
603 <pre>namespace detail{
605 template
<bool opt
>
608 template
<typename I, typename T
>
609 static void do_fill(I first, I last, typename boost::call_traits
<T
>::param_type val)
620 struct filler
<true
>
622 template
<typename I, typename T
>
623 static void do_fill(I first, I last, T val)
625 memset(first, val, last-first);
631 template
<class I, class T
>
632 inline void fill(I first, I last, const T
& val)
634 enum{ can_opt = boost::is_pointer
<I
>::value
635 && boost::is_arithmetic
<T
>::value
636 && (sizeof(T) ==
1) };
637 typedef detail::filler
<can_opt
> filler_t;
638 filler_t::template do_fill
<I,T
>(first, last, val);
641 <p>Footnote: the reason that this is
"optimal
" for
642 small built-in types is that with the value passed as
"T
643 const
" instead of
"const T
&" 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>
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
"thin
655 wrapper
" 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
<>::do_fill,
658 which does use call_traits.
</p>
662 <p>The following notes are intended to briefly describe the
663 rational behind choices made in call_traits.
</p>
665 <p>All user-defined types follow
"existing practice
"
666 and need no comment.
</p>
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
"T const
" 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>
675 <p>Pointers follow the same rational as small built-in types.
</p>
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 "a reference to a reference is a reference
" (issue #
106,
682 submitted by Bjarne Stroustrup), call_traits
<T
>::value_type
683 and call_traits
<T
>::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>
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>
693 <pre>template
<class T
>
699 <p><font face=
"Times New Roman">In this case if we instantiate
700 A
<int[
2]
> 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>
705 <pre>template
<class T
>
706 void A
<T
>::foo(T t)
708 T dup(t); // doesn't compile for case that T is an array.
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
715 <pre>template
<class T
>
718 void foo(typename call_traits
<T
>::value_type t);
721 template
<class T
>
722 void A
<T
>::foo(typename call_traits
<T
>::value_type t)
724 typename call_traits
<T
>::value_type dup(t); // OK even if T is an array type.
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
741 <p>Revised
01 September
2000</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