diff options
author | Dave Abrahams <dave@boostpro.com> | 2001-02-12 03:17:54 +0000 |
---|---|---|
committer | Dave Abrahams <dave@boostpro.com> | 2001-02-12 03:17:54 +0000 |
commit | 0d43d674c1b01e3ea659b004f2f26fecb04235c1 (patch) | |
tree | 02808c274afad866985a38b480d30e69cf5135ef /more/generic_programming.html | |
parent | ab0a78f814a389b7a1868251eec94c10e9ddff90 (diff) | |
download | boost-0d43d674c1b01e3ea659b004f2f26fecb04235c1.tar.gz |
Initial checkin
[SVN r9146]
Diffstat (limited to 'more/generic_programming.html')
-rw-r--r-- | more/generic_programming.html | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/more/generic_programming.html b/more/generic_programming.html new file mode 100644 index 0000000000..9f3f85c83a --- /dev/null +++ b/more/generic_programming.html @@ -0,0 +1,175 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> + + <meta name="generator" content="HTML Tidy, see www.w3.org"> + <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> + <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> + <meta name="ProgId" content="FrontPage.Editor.Document"> + + <title>Generic Programming Techniques</title> + + <img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" + width="277" height="86"> + + <h1>Generic Programming Techniques</h1> + + <p>This is an incomplete survey of some of the generic programming + techniques used in the <a href="../index.htm">boost</a> libraries. + + <h2>Table of Contents</h2> + + <ul> + <li><a href="#traits">Traits</a> + + <li><a href="#type_generator">Type Generators</a> + + <li><a href="#object_generator">Object Generator</a> + + <li><a href="#policies">Policies Classes</a> + </ul> + + <h2><a name="traits">Traits</a></h2> + + <p>A traits class provides a way of associating information with another + type. For example, the class template <tt><a href= + "http://www.sgi.com/tech/stl/iterator_traits.html">std::iterator_traits<T></a></tt> + looks something like this: + + <blockquote> +<pre> +template <class Iterator> +struct iterator_traits { + typedef ... iterator_category; + typedef ... value_type; + typedef ... difference_type; + typedef ... pointer; + typedef ... reference; +}; +</pre> + </blockquote> + The traits' <tt>value_type</tt> gives generic code the type which the + iterator is "pointing at", while the <tt>iterator_category</tt> can be used + to select more efficient algorithms depending on the iterator's + capabilities. + + <p>A key feature of traits templates is that they're <i>non-intrusive</i>: + they allow us to associate information with arbitrary types, including + built-in types and types defined in third-party libraries, Normally, traits + are specified for a particular type by (partially) specializing the traits + template. + + <p>For an in-depth description of <tt>std::type_traits</tt>, see <a href= + "http://www.sgi.com/tech/stl/iterator_traits.html">this page</a> provided + by SGI. Another very different expression of the traits idiom in the + standard is <tt>std::numeric_limits<T></tt> which provides constants + describing the range and capabilities of numeric types. + + <h2><a name="type_generator">Type Generators</a></h2> + + <p>A <i>type generator</i> is a template whose only purpose is to + synthesize a single new type based on its template argument(s). The + generated type is usually expressed as a nested typedef named, + appropriately <tt>type</tt>. A type generator is usually used to + consolidate a complicated type expression into a simple one, as in + <tt>boost::<a href= + "../libs/utility/filter_iterator.hpp">filter_iterator_generator</a></tt>, + which looks something like this: + + <blockquote> +<pre> +template <class Predicate, class Iterator, + class Value = <i>complicated default</i>, + class Reference = <i>complicated default</i>, + class Pointer = <i>complicated default</i>, + class Category = <i>complicated default</i>, + class Distance = <i>complicated default</i> + > +struct filter_iterator_generator { + typedef iterator_adaptor< + Iterator,filter_iterator_policies<Predicate,Iterator>, + Value,Reference,Pointer,Category,Distance> <b>type</b>; +}; +</pre> + </blockquote> + + <p>Now, that's complicated, but producing an adapted filter iterator is + much easier. You can usually just write: + + <blockquote> +<pre> +boost::filter_iterator_generator<my_predicate,my_base_iterator>::type +</pre> + </blockquote> + + <h2><a name="object_generator">Object Generators</a></h2> + + <p>An <i>object generator</i> is a function template whose only purpose is + to construct a new object out of its arguments. Think of it as a kind of + generic constructor. An object generator may be more useful than a plain + constructor when the exact type to be generated is difficult or impossible + to express and the result of the generator can be passed directly to a + function rather than stored in a variable. Most object generators are named + with the prefix "<tt>make_</tt>", after <tt>std::<a href= + "http://www.sgi.com/tech/stl/pair.html">make_pair</a>(const T&, const U&)</tt>. + + <p>Here is an example, using another standard object generator, <tt>std::<a + href= + "http://www.sgi.com/tech/stl/back_insert_iterator.html">back_inserter</a>()</tt>: + + <blockquote> +<pre> +// Append the items in [start, finish) to c +template <class Container, class Iterator> +void append_sequence(Container& c, Iterator start, Iterator finish) +{ + std::copy(start, finish, <b>std::back_inserter</b>(c)); +} +</pre> + </blockquote> + + <p>Without using the object generator the example above would look like: + write: + + <blockquote> +<pre> +// Append the items in [start, finish) to c +template <class Container, class Iterator> +void append_sequence(Container& c, Iterator start, Iterator finish) +{ + std::copy(start, finish, <b>std::back_insert_iterator<Container></b>(c)); +} +</pre> + </blockquote> + + <p>As expressions get more complicated the need to reduce the verbosity of + type specification gets more compelling. + + <h2><a name="policies">Policies Classes</a></h2> + + <p>Policies classes are a simple idea we first saw described by <a href= + "mailto:andrewalex@hotmail.com">Andrei Alexandrescu</a>, but which we + snapped up and quickly applied in the <a href= + "../libs/utility/iterator_adaptors.htm">Iterator Adaptors</a> library. A + policies class is a template parameter used to transmit behaviors. A + detailed description by Andrei is available in <a href= + "http://www.cs.ualberta.ca/~hoover/cmput401/XP-Notes/xp-conf/Papers/7_3_Alexandrescu.pdf"> + this paper</a>. He writes: + + <blockquote> + <p>Policy classes are implementations of punctual design choices. They + are inherited from, or contained within, other classes. They provide + different strategies under the same syntactic interface. A class using + policies is templated having one template parameter for each policy it + uses. This allows the user to select the policies needed. + + <p>The power of policy classes comes from their ability to combine + freely. By combining several policy classes in a template class with + multiple parameters, one achieves combinatorial behaviors with a linear + amount of code. + </blockquote> + + <p> Andrei's description of policies describe their power as being derived + from their granularity and orthogonality. Boost has probably diluted the + distinction in the <a href="../libs/utility/iterator_adaptors.htm">Iterator + Adaptors</a> library, where we transmit all of an adapted iterator's + behavior in a single policies class. + |