generic_programming.html 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
  2. <meta name="generator" content="HTML Tidy, see www.w3.org">
  3. <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
  4. <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
  5. <meta name="ProgId" content="FrontPage.Editor.Document">
  6. <title>Generic Programming Techniques</title>
  7. <img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
  8. width="277" height="86">
  9. <h1>Generic Programming Techniques</h1>
  10. <p>This is an incomplete survey of some of the generic programming
  11. techniques used in the <a href="../index.htm">boost</a> libraries.
  12. <h2>Table of Contents</h2>
  13. <ul>
  14. <li><a href="#traits">Traits</a>
  15. <li><a href="#type_generator">Type Generators</a>
  16. <li><a href="#object_generator">Object Generator</a>
  17. <li><a href="#policies">Policies Classes</a>
  18. </ul>
  19. <h2><a name="traits">Traits</a></h2>
  20. <p>A traits class provides a way of associating information with another
  21. type. For example, the class template <tt><a href=
  22. "http://www.sgi.com/tech/stl/iterator_traits.html">std::iterator_traits&lt;T&gt;</a></tt>
  23. looks something like this:
  24. <blockquote>
  25. <pre>
  26. template &lt;class Iterator&gt;
  27. struct iterator_traits {
  28. typedef ... iterator_category;
  29. typedef ... value_type;
  30. typedef ... difference_type;
  31. typedef ... pointer;
  32. typedef ... reference;
  33. };
  34. </pre>
  35. </blockquote>
  36. The traits' <tt>value_type</tt> gives generic code the type which the
  37. iterator is "pointing at", while the <tt>iterator_category</tt> can be used
  38. to select more efficient algorithms depending on the iterator's
  39. capabilities.
  40. <p>A key feature of traits templates is that they're <i>non-intrusive</i>:
  41. they allow us to associate information with arbitrary types, including
  42. built-in types and types defined in third-party libraries, Normally, traits
  43. are specified for a particular type by (partially) specializing the traits
  44. template.
  45. <p>For an in-depth description of <tt>std::type_traits</tt>, see <a href=
  46. "http://www.sgi.com/tech/stl/iterator_traits.html">this page</a> provided
  47. by SGI. Another very different expression of the traits idiom in the
  48. standard is <tt>std::numeric_limits&lt;T&gt;</tt> which provides constants
  49. describing the range and capabilities of numeric types.
  50. <h2><a name="type_generator">Type Generators</a></h2>
  51. <p>A <i>type generator</i> is a template whose only purpose is to
  52. synthesize a single new type based on its template argument(s). The
  53. generated type is usually expressed as a nested typedef named,
  54. appropriately <tt>type</tt>. A type generator is usually used to
  55. consolidate a complicated type expression into a simple one, as in
  56. <tt>boost::<a href=
  57. "../libs/utility/filter_iterator.hpp">filter_iterator_generator</a></tt>,
  58. which looks something like this:
  59. <blockquote>
  60. <pre>
  61. template &lt;class Predicate, class Iterator,
  62. class Value = <i>complicated default</i>,
  63. class Reference = <i>complicated default</i>,
  64. class Pointer = <i>complicated default</i>,
  65. class Category = <i>complicated default</i>,
  66. class Distance = <i>complicated default</i>
  67. &gt;
  68. struct filter_iterator_generator {
  69. typedef iterator_adaptor&lt;
  70. Iterator,filter_iterator_policies&lt;Predicate,Iterator&gt;,
  71. Value,Reference,Pointer,Category,Distance&gt; <b>type</b>;
  72. };
  73. </pre>
  74. </blockquote>
  75. <p>Now, that's complicated, but producing an adapted filter iterator is
  76. much easier. You can usually just write:
  77. <blockquote>
  78. <pre>
  79. boost::filter_iterator_generator&lt;my_predicate,my_base_iterator&gt;::type
  80. </pre>
  81. </blockquote>
  82. <h2><a name="object_generator">Object Generators</a></h2>
  83. <p>An <i>object generator</i> is a function template whose only purpose is
  84. to construct a new object out of its arguments. Think of it as a kind of
  85. generic constructor. An object generator may be more useful than a plain
  86. constructor when the exact type to be generated is difficult or impossible
  87. to express and the result of the generator can be passed directly to a
  88. function rather than stored in a variable. Most object generators are named
  89. with the prefix "<tt>make_</tt>", after <tt>std::<a href=
  90. "http://www.sgi.com/tech/stl/pair.html">make_pair</a>(const T&amp;, const U&amp;)</tt>.
  91. <p>Here is an example, using another standard object generator, <tt>std::<a
  92. href=
  93. "http://www.sgi.com/tech/stl/back_insert_iterator.html">back_inserter</a>()</tt>:
  94. <blockquote>
  95. <pre>
  96. // Append the items in [start, finish) to c
  97. template &lt;class Container, class Iterator&gt;
  98. void append_sequence(Container&amp; c, Iterator start, Iterator finish)
  99. {
  100. std::copy(start, finish, <b>std::back_inserter</b>(c));
  101. }
  102. </pre>
  103. </blockquote>
  104. <p>Without using the object generator the example above would look like:
  105. write:
  106. <blockquote>
  107. <pre>
  108. // Append the items in [start, finish) to c
  109. template &lt;class Container, class Iterator&gt;
  110. void append_sequence(Container&amp; c, Iterator start, Iterator finish)
  111. {
  112. std::copy(start, finish, <b>std::back_insert_iterator&lt;Container&gt;</b>(c));
  113. }
  114. </pre>
  115. </blockquote>
  116. <p>As expressions get more complicated the need to reduce the verbosity of
  117. type specification gets more compelling.
  118. <h2><a name="policies">Policies Classes</a></h2>
  119. <p>Policies classes are a simple idea we first saw described by <a href=
  120. "mailto:andrewalex@hotmail.com">Andrei Alexandrescu</a>, but which we
  121. snapped up and quickly applied in the <a href=
  122. "../libs/utility/iterator_adaptors.htm">Iterator Adaptors</a> library. A
  123. policies class is a template parameter used to transmit behaviors. A
  124. detailed description by Andrei is available in <a href=
  125. "http://www.cs.ualberta.ca/~hoover/cmput401/XP-Notes/xp-conf/Papers/7_3_Alexandrescu.pdf">
  126. this paper</a>. He writes:
  127. <blockquote>
  128. <p>Policy classes are implementations of punctual design choices. They
  129. are inherited from, or contained within, other classes. They provide
  130. different strategies under the same syntactic interface. A class using
  131. policies is templated having one template parameter for each policy it
  132. uses. This allows the user to select the policies needed.
  133. <p>The power of policy classes comes from their ability to combine
  134. freely. By combining several policy classes in a template class with
  135. multiple parameters, one achieves combinatorial behaviors with a linear
  136. amount of code.
  137. </blockquote>
  138. <p> Andrei's description of policies describe their power as being derived
  139. from their granularity and orthogonality. Boost has probably diluted the
  140. distinction in the <a href="../libs/utility/iterator_adaptors.htm">Iterator
  141. Adaptors</a> library, where we transmit all of an adapted iterator's
  142. behavior in a single policies class.
粤ICP备19079148号