| [29] | 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 | <<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1> | 
|---|
 | 17 |  | 
|---|
 | 18 | <p>All of the contents of <boost/call_traits.hpp> are | 
|---|
 | 19 | defined inside namespace boost.</p> | 
|---|
 | 20 |  | 
|---|
 | 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 | 
|---|
 | 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<T>::value_type</code></p> | 
|---|
 | 61 |         </td> | 
|---|
 | 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> | 
|---|
 | 67 |         </td> | 
|---|
 | 68 |     </tr> | 
|---|
 | 69 |     <tr> | 
|---|
 | 70 |         <td valign="top" width="17%"><p align="center">T&<br> | 
|---|
 | 71 |         (return value)</p> | 
|---|
 | 72 |         </td> | 
|---|
 | 73 |         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::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&.</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&<br> | 
|---|
 | 84 |         (return value)</p> | 
|---|
 | 85 |         </td> | 
|---|
 | 86 |         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::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&.</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&<br> | 
|---|
 | 97 |         (function parameter)</p> | 
|---|
 | 98 |         </td> | 
|---|
 | 99 |         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p> | 
|---|
 | 100 |         </td> | 
|---|
 | 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> | 
|---|
 | 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 "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> | 
|---|
 | 131 | </ol> | 
|---|
 | 132 |  | 
|---|
 | 133 | <p> </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%"> </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> </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%"> </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> </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 "myclass", 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%"> </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&</p> | 
|---|
 | 374 |         </td> | 
|---|
 | 375 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 376 |         myclass&</p> | 
|---|
 | 377 |         </td> | 
|---|
 | 378 |         <td valign="top" width="17%"><p align="center">myclass | 
|---|
 | 379 |         const&</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&</p> | 
|---|
 | 392 |         </td> | 
|---|
 | 393 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 394 |         int&</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*&</p> | 
|---|
 | 409 |         </td> | 
|---|
 | 410 |         <td valign="top" width="17%"><p align="center">int*const&</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&</p> | 
|---|
 | 421 |         </td> | 
|---|
 | 422 |         <td valign="top" width="17%"><p align="center">int&</p> | 
|---|
 | 423 |         </td> | 
|---|
 | 424 |         <td valign="top" width="17%"><p align="center">int&</p> | 
|---|
 | 425 |         </td> | 
|---|
 | 426 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 427 |         int&</p> | 
|---|
 | 428 |         </td> | 
|---|
 | 429 |         <td valign="top" width="17%"><p align="center">int&</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&</p> | 
|---|
 | 438 |         </td> | 
|---|
 | 439 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 440 |         int&</p> | 
|---|
 | 441 |         </td> | 
|---|
 | 442 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 443 |         int&</p> | 
|---|
 | 444 |         </td> | 
|---|
 | 445 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 446 |         int&</p> | 
|---|
 | 447 |         </td> | 
|---|
 | 448 |         <td valign="top" width="17%"><p align="center">const | 
|---|
 | 449 |         int&</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(&)[3]</p> | 
|---|
 | 462 |         </td> | 
|---|
 | 463 |         <td valign="top" width="17%"><p align="center">const int(&)[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(&)[3]</p> | 
|---|
 | 479 |         </td> | 
|---|
 | 480 |         <td valign="top" width="17%"><p align="center">const int(&)[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> </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 <class T> | 
|---|
 | 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<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; | 
|---|
 | 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 <class Operation>  | 
|---|
 | 533 | class binder1st :  | 
|---|
 | 534 |    public unary_function<typename Operation::second_argument_type, typename Operation::result_type>  | 
|---|
 | 535 | {  | 
|---|
 | 536 | protected:  | 
|---|
 | 537 |    Operation op;  | 
|---|
 | 538 |    typename Operation::first_argument_type value;  | 
|---|
 | 539 | public:  | 
|---|
 | 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;  | 
|---|
 | 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<typename Operation::second_argument_type>::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 "reference to reference" 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 | "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> | 
|---|
 | 570 |  | 
|---|
 | 571 | <pre>template <class T1, class T2> | 
|---|
 | 572 | std::pair< | 
|---|
 | 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) | 
|---|
 | 576 | { | 
|---|
 | 577 |    return std::pair< | 
|---|
 | 578 |       typename boost::call_traits<T1>::value_type,  | 
|---|
 | 579 |       typename boost::call_traits<T2>::value_type>(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 "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> | 
|---|
 | 589 |  | 
|---|
 | 590 | <h4><a name="ex4"></a>Example 4 (optimising fill):</h4> | 
|---|
 | 591 |  | 
|---|
 | 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 | 
|---|
 | 601 | call_traits:</p> | 
|---|
 | 602 |  | 
|---|
 | 603 | <pre>namespace detail{ | 
|---|
 | 604 |  | 
|---|
 | 605 | template <bool opt> | 
|---|
 | 606 | struct filler | 
|---|
 | 607 | { | 
|---|
 | 608 |    template <typename I, typename T> | 
|---|
 | 609 |    static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val) | 
|---|
 | 610 |    { | 
|---|
 | 611 |       while(first != last) | 
|---|
 | 612 |       { | 
|---|
 | 613 |          *first = val; | 
|---|
 | 614 |          ++first; | 
|---|
 | 615 |       } | 
|---|
 | 616 |    } | 
|---|
 | 617 | }; | 
|---|
 | 618 |  | 
|---|
 | 619 | template <> | 
|---|
 | 620 | struct filler<true> | 
|---|
 | 621 | { | 
|---|
 | 622 |    template <typename I, typename T> | 
|---|
 | 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 <class I, class T> | 
|---|
 | 632 | inline void fill(I first, I last, const T& val) | 
|---|
 | 633 | { | 
|---|
 | 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); | 
|---|
 | 639 | }</pre> | 
|---|
 | 640 |  | 
|---|
 | 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> | 
|---|
 | 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 "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> | 
|---|
 | 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 "existing practice" | 
|---|
 | 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 "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> | 
|---|
 | 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 | "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> | 
|---|
 | 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 <class T> | 
|---|
 | 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<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> | 
|---|
 | 704 |  | 
|---|
 | 705 | <pre>template <class T> | 
|---|
 | 706 | void A<T>::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 <class T> | 
|---|
 | 716 | struct A | 
|---|
 | 717 | { | 
|---|
 | 718 |    void foo(typename call_traits<T>::value_type t); | 
|---|
 | 719 | }; | 
|---|
 | 720 |  | 
|---|
 | 721 | template <class T> | 
|---|
 | 722 | void A<T>::foo(typename call_traits<T>::value_type t) | 
|---|
 | 723 | { | 
|---|
 | 724 |    typename call_traits<T>::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>© Copyright boost.org 2000. Permission to copy, use, modify, | 
|---|
 | 744 | sell and distribute this document is granted provided this | 
|---|
 | 745 | copyright notice appears in all copies. This document is provided | 
|---|
 | 746 | "as is" without express or implied warranty, and with | 
|---|
 | 747 | no claim as to its suitability for any purpose.</p> | 
|---|
 | 748 |  | 
|---|
 | 749 | <p>Based on contributions by Steve Cleary, Beman Dawes, Howard | 
|---|
 | 750 | Hinnant and John Maddock.</p> | 
|---|
 | 751 |  | 
|---|
 | 752 | <p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John | 
|---|
 | 753 | Maddock</a>, the latest version of this file can be found at <a | 
|---|
 | 754 | href="http://www.boost.org/">www.boost.org</a>, and the boost | 
|---|
 | 755 | discussion list at <a | 
|---|
 | 756 | href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p> | 
|---|
 | 757 |  | 
|---|
 | 758 | <p>.</p> | 
|---|
 | 759 |  | 
|---|
 | 760 | <p> </p> | 
|---|
 | 761 |  | 
|---|
 | 762 | <p> </p> | 
|---|
 | 763 | </body> | 
|---|
 | 764 | </html> | 
|---|
 | 765 |  | 
|---|