background.html 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Background and Tutorial</title>
  5. <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.TypeTraits">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.TypeTraits">
  9. <link rel="prev" href="intro.html" title="Introduction">
  10. <link rel="next" href="category.html" title="Type Traits by Category">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="intro.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="category.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="boost_typetraits.background"></a><a class="link" href="background.html" title="Background and Tutorial">Background and Tutorial</a>
  28. </h2></div></div></div>
  29. <p>
  30. The following is an updated version of the article "C++ Type traits"
  31. by John Maddock and Steve Cleary that appeared in the October 2000 issue of
  32. <a href="http://www.ddj.com" target="_top">Dr Dobb's Journal</a>.
  33. </p>
  34. <p>
  35. Generic programming (writing code which works with any data type meeting a
  36. set of requirements) has become the method of choice for providing reusable
  37. code. However, there are times in generic programming when "generic"
  38. just isn't good enough - sometimes the differences between types are too large
  39. for an efficient generic implementation. This is when the traits technique
  40. becomes important - by encapsulating those properties that need to be considered
  41. on a type by type basis inside a traits class, we can minimize the amount of
  42. code that has to differ from one type to another, and maximize the amount of
  43. generic code.
  44. </p>
  45. <p>
  46. Consider an example: when working with character strings, one common operation
  47. is to determine the length of a null terminated string. Clearly it's possible
  48. to write generic code that can do this, but it turns out that there are much
  49. more efficient methods available: for example, the C library functions <code class="computeroutput"><span class="identifier">strlen</span></code> and <code class="computeroutput"><span class="identifier">wcslen</span></code>
  50. are usually written in assembler, and with suitable hardware support can be
  51. considerably faster than a generic version written in C++. The authors of the
  52. C++ standard library realized this, and abstracted the properties of <code class="computeroutput"><span class="keyword">char</span></code> and <code class="computeroutput"><span class="keyword">wchar_t</span></code>
  53. into the class <code class="computeroutput"><span class="identifier">char_traits</span></code>.
  54. Generic code that works with character strings can simply use <code class="computeroutput"><span class="identifier">char_traits</span><span class="special">&lt;&gt;::</span><span class="identifier">length</span></code> to determine the length of a null
  55. terminated string, safe in the knowledge that specializations of <code class="computeroutput"><span class="identifier">char_traits</span></code> will use the most appropriate
  56. method available to them.
  57. </p>
  58. <h5>
  59. <a name="boost_typetraits.background.h0"></a>
  60. <span class="phrase"><a name="boost_typetraits.background.type_traits"></a></span><a class="link" href="background.html#boost_typetraits.background.type_traits">Type
  61. Traits</a>
  62. </h5>
  63. <p>
  64. Class <code class="computeroutput"><span class="identifier">char_traits</span></code> is a classic
  65. example of a collection of type specific properties wrapped up in a single
  66. class - what Nathan Myers termed a <span class="emphasis"><em>baggage class</em></span><a class="link" href="background.html#background.references">[1]</a>. In the Boost type-traits library,
  67. we<a class="link" href="background.html#background.references">[2]</a> have written a set of very
  68. specific traits classes, each of which encapsulate a single trait from the
  69. C++ type system; for example, is a type a pointer or a reference type? Or does
  70. a type have a trivial constructor, or a const-qualifier? The type-traits classes
  71. share a unified design: each class inherits from the type <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a>
  72. if the type has the specified property and inherits from <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a>
  73. otherwise. As we will show, these classes can be used in generic programming
  74. to determine the properties of a given type and introduce optimizations that
  75. are appropriate for that case.
  76. </p>
  77. <p>
  78. The type-traits library also contains a set of classes that perform a specific
  79. transformation on a type; for example, they can remove a top-level const or
  80. volatile qualifier from a type. Each class that performs a transformation defines
  81. a single typedef-member <code class="computeroutput"><span class="identifier">type</span></code>
  82. that is the result of the transformation. All of the type-traits classes are
  83. defined inside namespace <code class="computeroutput"><span class="identifier">boost</span></code>;
  84. for brevity, namespace-qualification is omitted in most of the code samples
  85. given.
  86. </p>
  87. <h5>
  88. <a name="boost_typetraits.background.h1"></a>
  89. <span class="phrase"><a name="boost_typetraits.background.implementation"></a></span><a class="link" href="background.html#boost_typetraits.background.implementation">Implementation</a>
  90. </h5>
  91. <p>
  92. There are far too many separate classes contained in the type-traits library
  93. to give a full implementation here - see the source code in the Boost library
  94. for the full details - however, most of the implementation is fairly repetitive
  95. anyway, so here we will just give you a flavor for how some of the classes
  96. are implemented. Beginning with possibly the simplest class in the library,
  97. <code class="computeroutput"><span class="identifier">is_void</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> inherits
  98. from <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>
  99. only if <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="keyword">void</span></code>.
  100. </p>
  101. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  102. <span class="keyword">struct</span> <a class="link" href="reference/is_void.html" title="is_void">is_void</a> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a><span class="special">{};</span>
  103. <span class="keyword">template</span> <span class="special">&lt;&gt;</span>
  104. <span class="keyword">struct</span> <a class="link" href="reference/is_void.html" title="is_void">is_void</a><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a><span class="special">{};</span>
  105. </pre>
  106. <p>
  107. Here we define a primary version of the template class <code class="computeroutput"><a class="link" href="reference/is_void.html" title="is_void">is_void</a></code>,
  108. and provide a full-specialization when <code class="computeroutput"><span class="identifier">T</span></code>
  109. is <code class="computeroutput"><span class="keyword">void</span></code>. While full specialization
  110. of a template class is an important technique, sometimes we need a solution
  111. that is halfway between a fully generic solution, and a full specialization.
  112. This is exactly the situation for which the standards committee defined partial
  113. template-class specialization. As an example, consider the class <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_pointer</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>:
  114. here we needed a primary version that handles all the cases where T is not
  115. a pointer, and a partial specialization to handle all the cases where T is
  116. a pointer:
  117. </p>
  118. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  119. <span class="keyword">struct</span> <a class="link" href="reference/is_pointer.html" title="is_pointer">is_pointer</a> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a><span class="special">{};</span>
  120. <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  121. <span class="keyword">struct</span> <a class="link" href="reference/is_pointer.html" title="is_pointer">is_pointer</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">*&gt;</span> <span class="special">:</span> <span class="keyword">public</span> <a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a><span class="special">{};</span>
  122. </pre>
  123. <p>
  124. The syntax for partial specialization is somewhat arcane and could easily occupy
  125. an article in its own right; like full specialization, in order to write a
  126. partial specialization for a class, you must first declare the primary template.
  127. The partial specialization contains an extra &lt;...&gt; after the class name
  128. that contains the partial specialization parameters; these define the types
  129. that will bind to that partial specialization rather than the default template.
  130. The rules for what can appear in a partial specialization are somewhat convoluted,
  131. but as a rule of thumb if you can legally write two function overloads of the
  132. form:
  133. </p>
  134. <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span><span class="special">);</span>
  135. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">U</span><span class="special">);</span>
  136. </pre>
  137. <p>
  138. Then you can also write a partial specialization of the form:
  139. </p>
  140. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  141. <span class="keyword">class</span> <span class="identifier">c</span><span class="special">{</span> <span class="comment">/*details*/</span> <span class="special">};</span>
  142. <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  143. <span class="keyword">class</span> <span class="identifier">c</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;{</span> <span class="comment">/*details*/</span> <span class="special">};</span>
  144. </pre>
  145. <p>
  146. This rule is by no means foolproof, but it is reasonably simple to remember
  147. and close enough to the actual rule to be useful for everyday use.
  148. </p>
  149. <p>
  150. As a more complex example of partial specialization consider the class <code class="computeroutput"><span class="identifier">remove_extent</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>. This
  151. class defines a single typedef-member <code class="computeroutput"><span class="identifier">type</span></code>
  152. that is the same type as T but with any top-level array bounds removed; this
  153. is an example of a traits class that performs a transformation on a type:
  154. </p>
  155. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  156. <span class="keyword">struct</span> <a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a>
  157. <span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
  158. <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span><span class="special">&gt;</span>
  159. <span class="keyword">struct</span> <a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">[</span><span class="identifier">N</span><span class="special">]&gt;</span>
  160. <span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
  161. </pre>
  162. <p>
  163. The aim of <code class="computeroutput"><a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a></code>
  164. is this: imagine a generic algorithm that is passed an array type as a template
  165. parameter, <code class="computeroutput"><a class="link" href="reference/remove_extent.html" title="remove_extent">remove_extent</a></code>
  166. provides a means of determining the underlying type of the array. For example
  167. <code class="computeroutput"><span class="identifier">remove_extent</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">[</span><span class="number">4</span><span class="special">][</span><span class="number">5</span><span class="special">]&gt;::</span><span class="identifier">type</span></code> would evaluate to the type <code class="computeroutput"><span class="keyword">int</span><span class="special">[</span><span class="number">5</span><span class="special">]</span></code>. This example also shows that the number of
  168. template parameters in a partial specialization does not have to match the
  169. number in the default template. However, the number of parameters that appear
  170. after the class name do have to match the number and type of the parameters
  171. in the default template.
  172. </p>
  173. <h5>
  174. <a name="boost_typetraits.background.h2"></a>
  175. <span class="phrase"><a name="boost_typetraits.background.optimized_copy"></a></span><a class="link" href="background.html#boost_typetraits.background.optimized_copy">Optimized
  176. copy</a>
  177. </h5>
  178. <p>
  179. As an example of how the type traits classes can be used, consider the standard
  180. library algorithm copy:
  181. </p>
  182. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Iter2</span><span class="special">&gt;</span>
  183. <span class="identifier">Iter2</span> <span class="identifier">copy</span><span class="special">(</span><span class="identifier">Iter1</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iter1</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">Iter2</span> <span class="identifier">out</span><span class="special">);</span>
  184. </pre>
  185. <p>
  186. Obviously, there's no problem writing a generic version of copy that works
  187. for all iterator types <code class="computeroutput"><span class="identifier">Iter1</span></code>
  188. and <code class="computeroutput"><span class="identifier">Iter2</span></code>; however, there are
  189. some circumstances when the copy operation can best be performed by a call
  190. to <code class="computeroutput"><span class="identifier">memcpy</span></code>. In order to implement
  191. copy in terms of <code class="computeroutput"><span class="identifier">memcpy</span></code> all
  192. of the following conditions need to be met:
  193. </p>
  194. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  195. <li class="listitem">
  196. Both of the iterator types <code class="computeroutput"><span class="identifier">Iter1</span></code>
  197. and <code class="computeroutput"><span class="identifier">Iter2</span></code> must be pointers.
  198. </li>
  199. <li class="listitem">
  200. Both <code class="computeroutput"><span class="identifier">Iter1</span></code> and <code class="computeroutput"><span class="identifier">Iter2</span></code> must point to the same type - excluding
  201. const and volatile-qualifiers.
  202. </li>
  203. <li class="listitem">
  204. The type pointed to by <code class="computeroutput"><span class="identifier">Iter1</span></code>
  205. must have a trivial assignment operator.
  206. </li>
  207. </ul></div>
  208. <p>
  209. By trivial assignment operator we mean that the type is either a scalar type<a class="link" href="background.html#background.references">[3]</a> or:
  210. </p>
  211. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  212. <li class="listitem">
  213. The type has no user defined assignment operator.
  214. </li>
  215. <li class="listitem">
  216. The type does not have any data members that are references.
  217. </li>
  218. <li class="listitem">
  219. All base classes, and all data member objects must have trivial assignment
  220. operators.
  221. </li>
  222. </ul></div>
  223. <p>
  224. If all these conditions are met then a type can be copied using <code class="computeroutput"><span class="identifier">memcpy</span></code> rather than using a compiler generated
  225. assignment operator. The type-traits library provides a class <code class="computeroutput"><a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a></code>,
  226. such that <code class="computeroutput"><span class="identifier">has_trivial_assign</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code> is true only if T has a trivial assignment
  227. operator. This class "just works" for scalar types, but has to be
  228. explicitly specialised for class/struct types that also happen to have a trivial
  229. assignment operator. In other words if <a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a>
  230. gives the wrong answer, it will give the "safe" wrong answer - that
  231. trivial assignment is not allowable.
  232. </p>
  233. <p>
  234. The code for an optimized version of copy that uses <code class="computeroutput"><span class="identifier">memcpy</span></code>
  235. where appropriate is given in <a class="link" href="examples/copy.html" title="An Optimized Version of std::copy">the
  236. examples</a>. The code begins by defining a template function <code class="computeroutput"><span class="identifier">do_copy</span></code> that performs a "slow but safe"
  237. copy. The last parameter passed to this function may be either a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>
  238. or a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">false_type</a></code>.
  239. Following that there is an overload of do_copy that uses <code class="computeroutput"><span class="identifier">memcpy</span></code>:
  240. this time the iterators are required to actually be pointers to the same type,
  241. and the final parameter must be a <code class="computeroutput"><a class="link" href="reference/integral_constant.html" title="integral_constant">true_type</a></code>.
  242. Finally, the version of <code class="computeroutput"><span class="identifier">copy</span></code>
  243. calls <code class="computeroutput"><span class="identifier">do_copy</span></code>, passing <code class="computeroutput"><a class="link" href="reference/has_trivial_assign.html" title="has_trivial_assign">has_trivial_assign</a><span class="special">&lt;</span><span class="identifier">value_type</span><span class="special">&gt;()</span></code> as the final parameter: this will dispatch
  244. to the optimized version where appropriate, otherwise it will call the "slow
  245. but safe version".
  246. </p>
  247. <h5>
  248. <a name="boost_typetraits.background.h3"></a>
  249. <span class="phrase"><a name="boost_typetraits.background.was_it_worth_it_"></a></span><a class="link" href="background.html#boost_typetraits.background.was_it_worth_it_">Was
  250. it worth it?</a>
  251. </h5>
  252. <p>
  253. It has often been repeated in these columns that "premature optimization
  254. is the root of all evil" <a class="link" href="background.html#background.references">[4]</a>.
  255. So the question must be asked: was our optimization premature? To put this
  256. in perspective the timings for our version of copy compared a conventional
  257. generic copy<a class="link" href="background.html#background.references">[5]</a> are shown in table
  258. 1.
  259. </p>
  260. <p>
  261. Clearly the optimization makes a difference in this case; but, to be fair,
  262. the timings are loaded to exclude cache miss effects - without this accurate
  263. comparison between algorithms becomes difficult. However, perhaps we can add
  264. a couple of caveats to the premature optimization rule:
  265. </p>
  266. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  267. <li class="listitem">
  268. If you use the right algorithm for the job in the first place then optimization
  269. will not be required; in some cases, memcpy is the right algorithm.
  270. </li>
  271. <li class="listitem">
  272. If a component is going to be reused in many places by many people then
  273. optimizations may well be worthwhile where they would not be so for a single
  274. case - in other words, the likelihood that the optimization will be absolutely
  275. necessary somewhere, sometime is that much higher. Just as importantly
  276. the perceived value of the stock implementation will be higher: there is
  277. no point standardizing an algorithm if users reject it on the grounds that
  278. there are better, more heavily optimized versions available.
  279. </li>
  280. </ul></div>
  281. <div class="table">
  282. <a name="boost_typetraits.background.time_taken_to_copy_1000_elements_using__copy_const_t___t_____times_in_micro_seconds_"></a><p class="title"><b>Table&#160;1.1.&#160;Time taken to copy 1000 elements using `copy&lt;const T*, T*&gt;` (times
  283. in micro-seconds)</b></p>
  284. <div class="table-contents"><table class="table" summary="Time taken to copy 1000 elements using `copy&lt;const T*, T*&gt;` (times
  285. in micro-seconds)">
  286. <colgroup>
  287. <col>
  288. <col>
  289. <col>
  290. </colgroup>
  291. <thead><tr>
  292. <th>
  293. <p>
  294. Version
  295. </p>
  296. </th>
  297. <th>
  298. <p>
  299. T
  300. </p>
  301. </th>
  302. <th>
  303. <p>
  304. Time
  305. </p>
  306. </th>
  307. </tr></thead>
  308. <tbody>
  309. <tr>
  310. <td>
  311. <p>
  312. "Optimized" copy
  313. </p>
  314. </td>
  315. <td>
  316. <p>
  317. char
  318. </p>
  319. </td>
  320. <td>
  321. <p>
  322. 0.99
  323. </p>
  324. </td>
  325. </tr>
  326. <tr>
  327. <td>
  328. <p>
  329. Conventional copy
  330. </p>
  331. </td>
  332. <td>
  333. <p>
  334. char
  335. </p>
  336. </td>
  337. <td>
  338. <p>
  339. 8.07
  340. </p>
  341. </td>
  342. </tr>
  343. <tr>
  344. <td>
  345. <p>
  346. "Optimized" copy
  347. </p>
  348. </td>
  349. <td>
  350. <p>
  351. int
  352. </p>
  353. </td>
  354. <td>
  355. <p>
  356. 2.52
  357. </p>
  358. </td>
  359. </tr>
  360. <tr>
  361. <td>
  362. <p>
  363. Conventional copy
  364. </p>
  365. </td>
  366. <td>
  367. <p>
  368. int
  369. </p>
  370. </td>
  371. <td>
  372. <p>
  373. 8.02
  374. </p>
  375. </td>
  376. </tr>
  377. </tbody>
  378. </table></div>
  379. </div>
  380. <br class="table-break"><h5>
  381. <a name="boost_typetraits.background.h4"></a>
  382. <span class="phrase"><a name="boost_typetraits.background.pair_of_references"></a></span><a class="link" href="background.html#boost_typetraits.background.pair_of_references">Pair
  383. of References</a>
  384. </h5>
  385. <p>
  386. The optimized copy example shows how type traits may be used to perform optimization
  387. decisions at compile-time. Another important usage of type traits is to allow
  388. code to compile that otherwise would not do so unless excessive partial specialization
  389. is used. This is possible by delegating partial specialization to the type
  390. traits classes. Our example for this form of usage is a pair that can hold
  391. references <a class="link" href="background.html#background.references">[6]</a>.
  392. </p>
  393. <p>
  394. First, let us examine the definition of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>, omitting
  395. the comparison operators, default constructor, and template copy constructor
  396. for simplicity:
  397. </p>
  398. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
  399. <span class="keyword">struct</span> <span class="identifier">pair</span>
  400. <span class="special">{</span>
  401. <span class="keyword">typedef</span> <span class="identifier">T1</span> <span class="identifier">first_type</span><span class="special">;</span>
  402. <span class="keyword">typedef</span> <span class="identifier">T2</span> <span class="identifier">second_type</span><span class="special">;</span>
  403. <span class="identifier">T1</span> <span class="identifier">first</span><span class="special">;</span>
  404. <span class="identifier">T2</span> <span class="identifier">second</span><span class="special">;</span>
  405. <span class="identifier">pair</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T1</span> <span class="special">&amp;</span> <span class="identifier">nfirst</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T2</span> <span class="special">&amp;</span> <span class="identifier">nsecond</span><span class="special">)</span>
  406. <span class="special">:</span><span class="identifier">first</span><span class="special">(</span><span class="identifier">nfirst</span><span class="special">),</span> <span class="identifier">second</span><span class="special">(</span><span class="identifier">nsecond</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
  407. <span class="special">};</span>
  408. </pre>
  409. <p>
  410. Now, this "pair" cannot hold references as it currently stands, because
  411. the constructor would require taking a reference to a reference, which is currently
  412. illegal <a class="link" href="background.html#background.references">[7]</a>. Let us consider what
  413. the constructor's parameters would have to be in order to allow "pair"
  414. to hold non-reference types, references, and constant references:
  415. </p>
  416. <div class="table">
  417. <a name="boost_typetraits.background.required_constructor_argument_types"></a><p class="title"><b>Table&#160;1.2.&#160;Required Constructor Argument Types</b></p>
  418. <div class="table-contents"><table class="table" summary="Required Constructor Argument Types">
  419. <colgroup>
  420. <col>
  421. <col>
  422. </colgroup>
  423. <thead><tr>
  424. <th>
  425. <p>
  426. Type of <code class="computeroutput"><span class="identifier">T1</span></code>
  427. </p>
  428. </th>
  429. <th>
  430. <p>
  431. Type of parameter to initializing constructor
  432. </p>
  433. </th>
  434. </tr></thead>
  435. <tbody>
  436. <tr>
  437. <td>
  438. <p>
  439. T
  440. </p>
  441. </td>
  442. <td>
  443. <p>
  444. const T &amp;
  445. </p>
  446. </td>
  447. </tr>
  448. <tr>
  449. <td>
  450. <p>
  451. T &amp;
  452. </p>
  453. </td>
  454. <td>
  455. <p>
  456. T &amp;
  457. </p>
  458. </td>
  459. </tr>
  460. <tr>
  461. <td>
  462. <p>
  463. const T &amp;
  464. </p>
  465. </td>
  466. <td>
  467. <p>
  468. const T &amp;
  469. </p>
  470. </td>
  471. </tr>
  472. </tbody>
  473. </table></div>
  474. </div>
  475. <br class="table-break"><p>
  476. A little familiarity with the type traits classes allows us to construct a
  477. single mapping that allows us to determine the type of parameter from the type
  478. of the contained class. The type traits classes provide a transformation <a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a>, which
  479. adds a reference to its type, unless it is already a reference.
  480. </p>
  481. <div class="table">
  482. <a name="boost_typetraits.background.using_add_reference_to_synthesize_the_correct_constructor_type"></a><p class="title"><b>Table&#160;1.3.&#160;Using add_reference to synthesize the correct constructor type</b></p>
  483. <div class="table-contents"><table class="table" summary="Using add_reference to synthesize the correct constructor type">
  484. <colgroup>
  485. <col>
  486. <col>
  487. <col>
  488. </colgroup>
  489. <thead><tr>
  490. <th>
  491. <p>
  492. Type of <code class="computeroutput"><span class="identifier">T1</span></code>
  493. </p>
  494. </th>
  495. <th>
  496. <p>
  497. Type of <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">T1</span></code>
  498. </p>
  499. </th>
  500. <th>
  501. <p>
  502. Type of <code class="computeroutput"><span class="identifier">add_reference</span><span class="special">&lt;</span><span class="keyword">const</span>
  503. <span class="identifier">T1</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
  504. </p>
  505. </th>
  506. </tr></thead>
  507. <tbody>
  508. <tr>
  509. <td>
  510. <p>
  511. T
  512. </p>
  513. </td>
  514. <td>
  515. <p>
  516. const T
  517. </p>
  518. </td>
  519. <td>
  520. <p>
  521. const T &amp;
  522. </p>
  523. </td>
  524. </tr>
  525. <tr>
  526. <td>
  527. <p>
  528. T &amp;
  529. </p>
  530. </td>
  531. <td>
  532. <p>
  533. T &amp; [8]
  534. </p>
  535. </td>
  536. <td>
  537. <p>
  538. T &amp;
  539. </p>
  540. </td>
  541. </tr>
  542. <tr>
  543. <td>
  544. <p>
  545. const T &amp;
  546. </p>
  547. </td>
  548. <td>
  549. <p>
  550. const T &amp;
  551. </p>
  552. </td>
  553. <td>
  554. <p>
  555. const T &amp;
  556. </p>
  557. </td>
  558. </tr>
  559. </tbody>
  560. </table></div>
  561. </div>
  562. <br class="table-break"><p>
  563. This allows us to build a primary template definition for <code class="computeroutput"><span class="identifier">pair</span></code>
  564. that can contain non-reference types, reference types, and constant reference
  565. types:
  566. </p>
  567. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
  568. <span class="keyword">struct</span> <span class="identifier">pair</span>
  569. <span class="special">{</span>
  570. <span class="keyword">typedef</span> <span class="identifier">T1</span> <span class="identifier">first_type</span><span class="special">;</span>
  571. <span class="keyword">typedef</span> <span class="identifier">T2</span> <span class="identifier">second_type</span><span class="special">;</span>
  572. <span class="identifier">T1</span> <span class="identifier">first</span><span class="special">;</span>
  573. <span class="identifier">T2</span> <span class="identifier">second</span><span class="special">;</span>
  574. <span class="identifier">pair</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T1</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nfirst</span><span class="special">,</span>
  575. <span class="identifier">boost</span><span class="special">::</span><a class="link" href="reference/add_reference.html" title="add_reference">add_reference</a><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T2</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">nsecond</span><span class="special">)</span>
  576. <span class="special">:</span><span class="identifier">first</span><span class="special">(</span><span class="identifier">nfirst</span><span class="special">),</span> <span class="identifier">second</span><span class="special">(</span><span class="identifier">nsecond</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
  577. <span class="special">};</span>
  578. </pre>
  579. <p>
  580. Add back in the standard comparison operators, default constructor, and template
  581. copy constructor (which are all the same), and you have a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code> that
  582. can hold reference types!
  583. </p>
  584. <p>
  585. This same extension could have been done using partial template specialization
  586. of <code class="computeroutput"><span class="identifier">pair</span></code>, but to specialize
  587. <code class="computeroutput"><span class="identifier">pair</span></code> in this way would require
  588. three partial specializations, plus the primary template. Type traits allows
  589. us to define a single primary template that adjusts itself auto-magically to
  590. any of these partial specializations, instead of a brute-force partial specialization
  591. approach. Using type traits in this fashion allows programmers to delegate
  592. partial specialization to the type traits classes, resulting in code that is
  593. easier to maintain and easier to understand.
  594. </p>
  595. <h5>
  596. <a name="boost_typetraits.background.h5"></a>
  597. <span class="phrase"><a name="boost_typetraits.background.conclusion"></a></span><a class="link" href="background.html#boost_typetraits.background.conclusion">Conclusion</a>
  598. </h5>
  599. <p>
  600. We hope that in this article we have been able to give you some idea of what
  601. type-traits are all about. A more complete listing of the available classes
  602. are in the boost documentation, along with further examples using type traits.
  603. Templates have enabled C++ uses to take the advantage of the code reuse that
  604. generic programming brings; hopefully this article has shown that generic programming
  605. does not have to sink to the lowest common denominator, and that templates
  606. can be optimal as well as generic.
  607. </p>
  608. <h5>
  609. <a name="boost_typetraits.background.h6"></a>
  610. <span class="phrase"><a name="boost_typetraits.background.acknowledgements"></a></span><a class="link" href="background.html#boost_typetraits.background.acknowledgements">Acknowledgements</a>
  611. </h5>
  612. <p>
  613. The authors would like to thank Beman Dawes and Howard Hinnant for their helpful
  614. comments when preparing this article.
  615. </p>
  616. <h5>
  617. <a name="boost_typetraits.background.h7"></a>
  618. <span class="phrase"><a name="boost_typetraits.background._anchor_id__background_references___references"></a></span><a class="link" href="background.html#boost_typetraits.background._anchor_id__background_references___references">References</a>
  619. </h5>
  620. <div class="orderedlist"><ol class="orderedlist" type="1">
  621. <li class="listitem">
  622. Nathan C. Myers, C++ Report, June 1995.
  623. </li>
  624. <li class="listitem">
  625. The type traits library is based upon contributions by Steve Cleary, Beman
  626. Dawes, Howard Hinnant and John Maddock: it can be found at www.boost.org.
  627. </li>
  628. <li class="listitem">
  629. A scalar type is an arithmetic type (i.e. a built-in integer or floating
  630. point type), an enumeration type, a pointer, a pointer to member, or a
  631. const- or volatile-qualified version of one of these types.
  632. </li>
  633. <li class="listitem">
  634. This quote is from Donald Knuth, ACM Computing Surveys, December 1974,
  635. pg 268.
  636. </li>
  637. <li class="listitem">
  638. The test code is available as part of the boost utility library (see algo_opt_examples.cpp),
  639. the code was compiled with gcc 2.95 with all optimisations turned on, tests
  640. were conducted on a 400MHz Pentium II machine running Microsoft Windows
  641. 98.
  642. </li>
  643. <li class="listitem">
  644. John Maddock and Howard Hinnant have submitted a "compressed_pair"
  645. library to Boost, which uses a technique similar to the one described here
  646. to hold references. Their pair also uses type traits to determine if any
  647. of the types are empty, and will derive instead of contain to conserve
  648. space -- hence the name "compressed".
  649. </li>
  650. <li class="listitem">
  651. This is actually an issue with the C++ Core Language Working Group (issue
  652. #106), submitted by Bjarne Stroustrup. The tentative resolution is to allow
  653. a "reference to a reference to T" to mean the same thing as a
  654. "reference to T", but only in template instantiation, in a method
  655. similar to multiple cv-qualifiers.
  656. </li>
  657. <li class="listitem">
  658. For those of you who are wondering why this shouldn't be const-qualified,
  659. remember that references are always implicitly constant (for example, you
  660. can't re-assign a reference). Remember also that "const T &amp;"
  661. is something completely different. For this reason, cv-qualifiers on template
  662. type arguments that are references are ignored.
  663. </li>
  664. </ol></div>
  665. </div>
  666. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  667. <td align="left"></td>
  668. <td align="right"><div class="copyright-footer">Copyright &#169; 2000, 2011 Adobe Systems Inc, David Abrahams,
  669. Frederic Bron, Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant,
  670. Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Alexander Nasonov, Thorsten
  671. Ottosen, Roman Perepelitsa, Robert Ramey, Jeremy Siek, Robert Stewart and Steven
  672. Watanabe<p>
  673. Distributed under the Boost Software License, Version 1.0. (See accompanying
  674. file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  675. </p>
  676. </div></td>
  677. </tr></table>
  678. <hr>
  679. <div class="spirit-nav">
  680. <a accesskey="p" href="intro.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="category.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  681. </div>
  682. </body>
  683. </html>