mirror of
https://github.com/boostorg/more.git
synced 2025-01-30 05:00:09 +08:00
"policies"->"policy"
Use better example for object generators [SVN r9209]
This commit is contained in:
parent
96c46091f0
commit
15b502391b
@ -1,16 +1,12 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||||
|
|
||||||
<title>Generic Programming Techniques</title>
|
<title>Generic Programming Techniques</title>
|
||||||
</head>
|
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
|
||||||
<img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
|
<img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
|
||||||
width="277" height="86">
|
width="277" height="86">
|
||||||
|
|
||||||
@ -36,25 +32,24 @@
|
|||||||
|
|
||||||
<li><a href="#object_generator">Object Generators</a>
|
<li><a href="#object_generator">Object Generators</a>
|
||||||
|
|
||||||
<li><a href="#policies">Policies Classes</a>
|
<li><a href="#policy">Policy Classes</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="introduction">Introduction</a></h2>
|
<h2><a name="introduction">Introduction</a></h2>
|
||||||
|
|
||||||
<p>Generic programming is about generalizing software components
|
<p>Generic programming is about generalizing software components so that
|
||||||
so that they can be easily reused in a wide variety of situations.
|
they can be easily reused in a wide variety of situations. In C++, class
|
||||||
In C++, class and function templates are particularly effective
|
and function templates are particularly effective mechanisms for generic
|
||||||
mechanisms for generic programming because they make the
|
programming because they make the generalization possible without
|
||||||
generalization possible without sacrificing efficiency.
|
sacrificing efficiency.
|
||||||
|
|
||||||
<p>As a simple example of generic programming, we will look at how
|
<p>As a simple example of generic programming, we will look at how one
|
||||||
one might generalize the <tt>memcpy()</tt> function of the
|
might generalize the <tt>memcpy()</tt> function of the C standard library.
|
||||||
C standard library. An implementation of <tt>memcpy()</tt>
|
An implementation of <tt>memcpy()</tt> might look like the following:
|
||||||
might look like the following:
|
<br>
|
||||||
<p>
|
<br>
|
||||||
<blockquote>
|
|
||||||
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
void* memcpy(void* region1, const void* region2, size_t n)
|
void* memcpy(void* region1, const void* region2, size_t n)
|
||||||
{
|
{
|
||||||
@ -66,33 +61,33 @@ void* memcpy(void* region1, const void* region2, size_t n)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
The <tt>memcpy()</tt> function is already generalized to some
|
The <tt>memcpy()</tt> function is already generalized to some extent by the
|
||||||
extent by the use of <tt>void*</tt> so that the function can be
|
use of <tt>void*</tt> so that the function can be used to copy arrays of
|
||||||
used to copy arrays of different kinds of data. But what if the
|
different kinds of data. But what if the data we would like to copy is not
|
||||||
data we would like to copy is not in an array? Perhaps it is in a
|
in an array? Perhaps it is in a linked list. Can we generalize the notion
|
||||||
linked list. Can we generalize the notion of copy to any sequence
|
of copy to any sequence of elements? Looking at the body of
|
||||||
of elements? Looking at the body of <tt>memcpy()</tt>, the
|
<tt>memcpy()</tt>, the function's <b><i>minimal requirements</i></b> are
|
||||||
function's <b><i>minimal requirements</i></b> are that it needs to
|
that it needs to to <i>traverse</i> through the sequence using some sort of
|
||||||
to <i>traverse</i> through the sequence using some sort of
|
pointer, <i>access</i> elements pointed to, <i>write</i> the elements to
|
||||||
pointer, <i>access</i> elements pointed to, <i>write</i> the
|
the destination, and <i>compare</i> pointers to know when to stop. The C++
|
||||||
elements to the destination, and <i>compare</i> pointers to know
|
standard library groups requirements such as these into
|
||||||
when to stop. The C++ standard library groups requirements such
|
<b><i>concepts</i></b>, in this case the <a href=
|
||||||
as these into <b><i>concepts</i></b>, in this case the <a
|
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> concept
|
||||||
href="http://www.sgi.com/tech/stl/InputIterator.html"> Input
|
(for <tt>region2</tt>) and the <a href=
|
||||||
Iterator</a> concept (for <tt>region2</tt>) and the <a
|
"http://www.sgi.com/tech/stl/OutputIterator.html">Output Iterator</a>
|
||||||
href="http://www.sgi.com/tech/stl/OutputIterator.html"> Output
|
concept (for <tt>region1</tt>).
|
||||||
Iterator</a> concept (for <tt>region1</tt>).
|
|
||||||
|
|
||||||
<p>If we rewrite the <tt>memcpy()</tt> as a function template, and
|
<p>If we rewrite the <tt>memcpy()</tt> as a function template, and use the
|
||||||
use the <a href="http://www.sgi.com/tech/stl/InputIterator.html">
|
<a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
|
||||||
Input Iterator</a> and <a
|
and <a href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||||
href="http://www.sgi.com/tech/stl/OutputIterator.html"> Output
|
|
||||||
Iterator</a> concepts to describe the requirements on the template
|
Iterator</a> concepts to describe the requirements on the template
|
||||||
parameters, we can implement a highly reusable <tt>copy()</tt>
|
parameters, we can implement a highly reusable <tt>copy()</tt> function in
|
||||||
function in the following way:
|
the following way:
|
||||||
<p>
|
<br>
|
||||||
<blockquote>
|
<br>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
template <typename InputIterator, typename OutputIterator>
|
template <typename InputIterator, typename OutputIterator>
|
||||||
OutputIterator
|
OutputIterator
|
||||||
@ -103,14 +98,16 @@ copy(InputIterator first, InputIterator last, OutputIterator result)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Using the generic <tt>copy()</tt> function, we can now copy
|
<p>Using the generic <tt>copy()</tt> function, we can now copy elements
|
||||||
elements from any kind of sequence, including a linked list that
|
from any kind of sequence, including a linked list that exports iterators
|
||||||
exports iterators such as <tt>std::<a
|
such as <tt>std::<a href=
|
||||||
href="http://www.sgi.com/tech/stl/List.html">list</a></tt>.
|
"http://www.sgi.com/tech/stl/List.html">list</a></tt>.
|
||||||
<p>
|
<br>
|
||||||
<blockquote>
|
<br>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -133,45 +130,38 @@ int main()
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="concept">Anatomy of a Concept</a></h2>
|
<h2><a name="concept">Anatomy of a Concept</a></h2>
|
||||||
|
A <b><i>concept</i></b> is a set requirements, where the requirements
|
||||||
A <b><i>concept</i></b> is a set requirements, where the
|
consist of valid expressions, associated types, invariants, and complexity
|
||||||
requirements consist of valid expressions, associated types,
|
guarantees. A type that satisfies the set of requirements is said to
|
||||||
invariants, and complexity guarantees. A type that satisfies the
|
<b><i>model</i></b> the concept. A concept can extend the requirements of
|
||||||
set of requirements is said to <b><i>model</i></b> the concept. A
|
another concept, which is called <b><i>refinement</i></b>.
|
||||||
concept can extend the requirements of another concept, which is
|
|
||||||
called <b><i>refinement</i></b>.
|
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a name="valid_expression"><b>Valid Expressions</b></a> are
|
<li><a name="valid_expression"><b>Valid Expressions</b></a> are C++
|
||||||
C++ expressions which must compile successfully for the
|
expressions which must compile successfully for the objects involved in
|
||||||
objects involved in the expression to be considered
|
the expression to be considered <i>models</i> of the concept.
|
||||||
<i>models</i> of the concept.
|
|
||||||
|
|
||||||
<li><a name="associated_type"><b>Associated Types</b></a> are
|
<li><a name="associated_type"><b>Associated Types</b></a> are types that
|
||||||
types that are related to the modeling type in that they
|
are related to the modeling type in that they participate in one or more
|
||||||
participate in one or more of the valid expressions. Typically
|
of the valid expressions. Typically associated types can be accessed
|
||||||
associated types can be accessed either through typedefs
|
either through typedefs nested within a class definition for the modeling
|
||||||
nested within a class definition for the modeling type, or
|
type, or they are accessed through a <a href="#traits">traits class</a>.
|
||||||
they are accessed through a <a href="#traits">traits
|
|
||||||
class</a>.
|
|
||||||
|
|
||||||
<li><b>Invariants</b> are run-time characteristics of the
|
<li><b>Invariants</b> are run-time characteristics of the objects that
|
||||||
objects that must always be true, that is, the functions involving
|
must always be true, that is, the functions involving the objects must
|
||||||
the objects must preserve these characteristics. The invariants
|
preserve these characteristics. The invariants often take the form of
|
||||||
often take the form of pre-conditions and post-conditions.
|
pre-conditions and post-conditions.
|
||||||
|
|
||||||
<li><b>Complexity Guarantees</b> are maximum limits on how long
|
<li><b>Complexity Guarantees</b> are maximum limits on how long the
|
||||||
the execution of one of the valid expressions will take, or how
|
execution of one of the valid expressions will take, or how much of
|
||||||
much of various resources its computation will use.
|
various resources its computation will use.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>The concepts used in the C++ Standard Library are documented at
|
<p>The concepts used in the C++ Standard Library are documented at the <a
|
||||||
the <a href="http://www.sgi.com/tech/stl/table_of_contents.html">
|
href="http://www.sgi.com/tech/stl/table_of_contents.html">SGI STL site</a>.
|
||||||
SGI STL site</a>.
|
|
||||||
|
|
||||||
<h2><a name="traits">Traits</a></h2>
|
<h2><a name="traits">Traits</a></h2>
|
||||||
|
|
||||||
@ -204,56 +194,49 @@ struct iterator_traits {
|
|||||||
are specified for a particular type by (partially) specializing the traits
|
are specified for a particular type by (partially) specializing the traits
|
||||||
template.
|
template.
|
||||||
|
|
||||||
<p>For an in-depth description of <tt>std::iterator_traits</tt>, see <a href=
|
<p>For an in-depth description of <tt>std::iterator_traits</tt>, see <a
|
||||||
"http://www.sgi.com/tech/stl/iterator_traits.html">this page</a> provided
|
href="http://www.sgi.com/tech/stl/iterator_traits.html">this page</a>
|
||||||
by SGI. Another very different expression of the traits idiom in the
|
provided by SGI. Another very different expression of the traits idiom in
|
||||||
standard is <tt>std::numeric_limits<T></tt> which provides constants
|
the standard is <tt>std::numeric_limits<T></tt> which provides
|
||||||
describing the range and capabilities of numeric types.
|
constants describing the range and capabilities of numeric types.
|
||||||
|
|
||||||
<h2><a name="tag_dispatching">Tag Dispatching</a></h2>
|
<h2><a name="tag_dispatching">Tag Dispatching</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>A technique that often goes hand in hand with traits classes is tag
|
||||||
A technique that often goes hand in hand with traits classes is
|
dispatching, which is a way of using function overloading to dispatch based
|
||||||
tag dispatching, which is a way of using function overloading to
|
on properties of a type. A good example of this is the implementation of
|
||||||
dispatch based on properties of a type. A good example of this is
|
the <a href=
|
||||||
the implementation of the <a
|
"http://www.sgi.com/tech/stl/advance.html"><tt>std::advance()</tt></a>
|
||||||
href="http://www.sgi.com/tech/stl/advance.html"><tt>std::advance()</tt></a>
|
function in the C++ Standard Library, which increments an iterator
|
||||||
function in the C++ Standard Library, which increments an
|
<tt>n</tt> times. Depending on the kind of iterator, there are different
|
||||||
iterator <tt>n</tt> times. Depending on the kind of iterator,
|
optimizations that can be applied in the implementation. If the iterator is
|
||||||
there are different optimizations that can be applied in the
|
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">random
|
||||||
implementation. If the iterator is <a
|
access</a> (can jump forward and backward arbitrary distances), then the
|
||||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">random
|
<tt>advance()</tt> function can simply be implemented with <tt>i += n</tt>,
|
||||||
access</a> (can jump forward and backward arbitrary distances),
|
and is very efficient: constant time. If the iterator is <a href=
|
||||||
then the <tt>advance()</tt> function can simply be implemented
|
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">bidirectional</a>,
|
||||||
with <tt>i += n</tt>, and is very efficient: constant time. If
|
then it makes sense for <tt>n</tt> to be negative, we can decrement the
|
||||||
the iterator is <a
|
iterator <tt>n</tt> times.
|
||||||
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">bidirectional</a>,
|
|
||||||
then it makes sense for <tt>n</tt> to be negative, we can
|
<p>The relation between tag dispatching and traits classes is that the
|
||||||
decrement the iterator <tt>n</tt> times.
|
property used for dispatching (in this case the <tt>iterator_category</tt>)
|
||||||
</p>
|
is accessed through a traits class. The main <tt>advance()</tt> function
|
||||||
<p>
|
uses the <a href=
|
||||||
The relation between tag dispatching and traits classes is
|
"http://www.sgi.com/tech/stl/iterator_traits.html"><tt>iterator_traits</tt></a>
|
||||||
that the property used for dispatching (in this case the
|
class to get the <tt>iterator_category</tt>. It then makes a call the the
|
||||||
<tt>iterator_category</tt>) is accessed through a traits class.
|
overloaded <tt>advance_dispatch()</tt> function. The appropriate
|
||||||
The main <tt>advance()</tt> function uses the <a
|
<tt>advance_dispatch()</tt> is selected by the compiler based on whatever
|
||||||
href="http://www.sgi.com/tech/stl/iterator_traits.html"><tt>iterator_traits</tt></a>
|
type the <tt>iterator_category</tt> resolves to, either <a href=
|
||||||
class to get the <tt>iterator_category</tt>. It then makes a call
|
"http://www.sgi.com/tech/stl/input_iterator_tag.html"><tt>input_iterator_tag</tt></a>,
|
||||||
the the overloaded <tt>advance_dispatch()</tt> function.
|
<a href=
|
||||||
The
|
"http://www.sgi.com/tech/stl/bidirectional_iterator_tag.html"><tt>bidirectional_iterator_tag</tt></a>,
|
||||||
appropriate <tt>advance_dispatch()</tt> is selected by the
|
or <a href=
|
||||||
compiler based on whatever type the <tt>iterator_category</tt>
|
"http://www.sgi.com/tech/stl/random_access_iterator_tag.html"><tt>random_access_iterator_tag</tt></a>.
|
||||||
resolves to, either <a
|
A <b><i>tag</i></b> is simply a class whose only purpose is to convey some
|
||||||
href="http://www.sgi.com/tech/stl/input_iterator_tag.html">
|
property for use in tag dispatching and similar techniques. Refer to <a
|
||||||
<tt>input_iterator_tag</tt></a>, <a
|
href="http://www.sgi.com/tech/stl/iterator_tags.html">this page</a> for a
|
||||||
href="http://www.sgi.com/tech/stl/bidirectional_iterator_tag.html">
|
more detailed description of iterator tags.
|
||||||
<tt>bidirectional_iterator_tag</tt></a>, or <a
|
|
||||||
href="http://www.sgi.com/tech/stl/random_access_iterator_tag.html">
|
|
||||||
<tt>random_access_iterator_tag</tt></a>. A <b><i>tag</i></b> is
|
|
||||||
simply a class whose only purpose is to convey some property for
|
|
||||||
use in tag dispatching and similar techniques. Refer to <a
|
|
||||||
href="http://www.sgi.com/tech/stl/iterator_tags.html">this
|
|
||||||
page</a> for a more detailed description of iterator tags.
|
|
||||||
</p>
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
namespace std {
|
namespace std {
|
||||||
@ -269,16 +252,16 @@ namespace std {
|
|||||||
|
|
||||||
template <class BidirectionalIterator, class Distance>
|
template <class BidirectionalIterator, class Distance>
|
||||||
void advance_dispatch(BidirectionalIterator& i, Distance n,
|
void advance_dispatch(BidirectionalIterator& i, Distance n,
|
||||||
<b>bidirectional_iterator_tag</b>) {
|
<b>bidirectional_iterator_tag</b>) {
|
||||||
if (n >= 0)
|
if (n >= 0)
|
||||||
while (n--) ++i;
|
while (n--) ++i;
|
||||||
else
|
else
|
||||||
while (n++) --i;
|
while (n++) --i;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class RandomAccessIterator, class Distance>
|
template <class RandomAccessIterator, class Distance>
|
||||||
void advance_dispatch(RandomAccessIterator& i, Distance n,
|
void advance_dispatch(RandomAccessIterator& i, Distance n,
|
||||||
<b>random_access_iterator_tag</b>) {
|
<b>random_access_iterator_tag</b>) {
|
||||||
i += n;
|
i += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,11 +294,11 @@ namespace std {
|
|||||||
<h2><a name="type_generator">Type Generators</a></h2>
|
<h2><a name="type_generator">Type Generators</a></h2>
|
||||||
|
|
||||||
<p>A <i>type generator</i> is a template whose only purpose is to
|
<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)<a
|
synthesize a single new type based on its template argument(s)<a href=
|
||||||
href="#1">[1]</a>. The generated type is usually expressed as a
|
"#1">[1]</a>. The generated type is usually expressed as a nested typedef
|
||||||
nested typedef named, appropriately <tt>type</tt>. A type
|
named, appropriately <tt>type</tt>. A type generator is usually used to
|
||||||
generator is usually used to consolidate a complicated type
|
consolidate a complicated type expression into a simple one, as in
|
||||||
expression into a simple one, as in <tt>boost::<a href=
|
<tt>boost::<a href=
|
||||||
"../libs/utility/filter_iterator.hpp">filter_iterator_generator</a></tt>,
|
"../libs/utility/filter_iterator.hpp">filter_iterator_generator</a></tt>,
|
||||||
which looks something like this:
|
which looks something like this:
|
||||||
|
|
||||||
@ -345,7 +328,6 @@ boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
|
|||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="object_generator">Object Generators</a></h2>
|
<h2><a name="object_generator">Object Generators</a></h2>
|
||||||
|
|
||||||
<p>An <i>object generator</i> is a function template whose only purpose is
|
<p>An <i>object generator</i> is a function template whose only purpose is
|
||||||
@ -353,35 +335,45 @@ boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
|
|||||||
generic constructor. An object generator may be more useful than a plain
|
generic constructor. An object generator may be more useful than a plain
|
||||||
constructor when the exact type to be generated is difficult or impossible
|
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
|
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
|
function rather than stored in a variable. Most Boost object generators are
|
||||||
with the prefix "<tt>make_</tt>", after <tt>std::<a href=
|
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>.
|
"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
|
<p>For example, given:
|
||||||
href=
|
|
||||||
"http://www.sgi.com/tech/stl/back_insert_iterator.html">back_inserter</a>()</tt>:
|
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
// Append the items in [start, finish) to c
|
struct widget {
|
||||||
template <class Container, class Iterator>
|
void tweak(int);
|
||||||
void append_sequence(Container& c, Iterator start, Iterator finish)
|
};
|
||||||
|
std::vector<widget *> widget_ptrs;
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
By chaining two standard object generators, <tt>std::<a href=
|
||||||
|
"http://www.dinkumware.com/htm_cpl/functio2.html#bind2nd">bind2nd</a>()</tt>
|
||||||
|
and <tt>std::<a href=
|
||||||
|
"http://www.dinkumware.com/htm_cpl/functio2.html#mem_fun">mem_fun</a>()</tt>,
|
||||||
|
we can easily tweak all widgets:
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
void tweak_all_widgets1(int arg)
|
||||||
{
|
{
|
||||||
std::copy(start, finish, <b>std::back_inserter</b>(c));
|
for_each(widget_ptrs.begin(), widget_ptrs.end(),
|
||||||
|
<b>bind2nd</b>(std::<b>mem_fun</b>(&widget::tweak), arg));
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Without using the object generator the example above would look like:
|
<p>Without using object generators the example above would look like this:
|
||||||
write:
|
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
// Append the items in [start, finish) to c
|
void tweak_all_widgets2(int arg)
|
||||||
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));
|
for_each(struct_ptrs.begin(), struct_ptrs.end(),
|
||||||
|
<b>std::binder2nd<std::mem_fun1_t<void, widget, int> ></b>(
|
||||||
|
std::<b>mem_fun1_t<void, widget, int></b>(&widget::tweak), arg));
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@ -389,15 +381,15 @@ void append_sequence(Container& c, Iterator start, Iterator finish)
|
|||||||
<p>As expressions get more complicated the need to reduce the verbosity of
|
<p>As expressions get more complicated the need to reduce the verbosity of
|
||||||
type specification gets more compelling.
|
type specification gets more compelling.
|
||||||
|
|
||||||
<h2><a name="policies">Policies Classes</a></h2>
|
<h2><a name="policy">Policy Classes</a></h2>
|
||||||
|
|
||||||
<p>A policies class is a template parameter used to transmit
|
<p>A policy class is a template parameter used to transmit behavior. An
|
||||||
behaviors. An example from the standard library is <tt>std::<a
|
example from the standard library is <tt>std::<a href=
|
||||||
href="http://www.dinkumware.com/htm_cpl/memory.html#allocator">allocator</a></tt>,
|
"http://www.dinkumware.com/htm_cpl/memory.html#allocator">allocator</a></tt>,
|
||||||
which supplies memory management behaviors to standard <a
|
which supplies memory management behaviors to standard <a href=
|
||||||
href="http://www.sgi.com/tech/stl/Container.html">containers</a>.
|
"http://www.sgi.com/tech/stl/Container.html">containers</a>.
|
||||||
|
|
||||||
<p>Policies classes have been explored in detail by <a href=
|
<p>Policy classes have been explored in detail by <a href=
|
||||||
"mailto:andrewalex@hotmail.com">Andrei Alexandrescu</a> in <a href=
|
"mailto:andrewalex@hotmail.com">Andrei Alexandrescu</a> in <a href=
|
||||||
"http://www.cs.ualberta.ca/~hoover/cmput401/XP-Notes/xp-conf/Papers/7_3_Alexandrescu.pdf">
|
"http://www.cs.ualberta.ca/~hoover/cmput401/XP-Notes/xp-conf/Papers/7_3_Alexandrescu.pdf">
|
||||||
this paper</a>. He writes:
|
this paper</a>. He writes:
|
||||||
@ -415,40 +407,38 @@ void append_sequence(Container& c, Iterator start, Iterator finish)
|
|||||||
amount of code.
|
amount of code.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Andrei's description of policies describe their power as being derived
|
<p>Andrei's description of policy classes describe their power as being
|
||||||
from their granularity and orthogonality. Boost has probably diluted the
|
derived from their granularity and orthogonality. Boost has probably
|
||||||
distinction in the <a href="../libs/utility/iterator_adaptors.htm">Iterator
|
diluted the distinction in the <a href=
|
||||||
Adaptors</a> library, where we transmit all of an adapted iterator's
|
"../libs/utility/iterator_adaptors.htm">Iterator Adaptors</a> library,
|
||||||
behavior in a single policies class. There is precedent for this, however:
|
where we transmit all of an adapted iterator's behavior in a single policy
|
||||||
<tt><a
|
class. There is precedent for this, however: <tt><a href=
|
||||||
href="http://www.dinkumware.com/htm_cpl/string2.html#char_traits">std::char_traits</a></tt>,
|
"http://www.dinkumware.com/htm_cpl/string2.html#char_traits">std::char_traits</a></tt>,
|
||||||
despite its name, acts as a policies class that determines the behaviors of
|
despite its name, acts as a policies class that determines the behaviors of
|
||||||
<a
|
<a href=
|
||||||
href="http://www.dinkumware.com/htm_cpl/string2.html#basic_string">std::basic_string</a>.
|
"http://www.dinkumware.com/htm_cpl/string2.html#basic_string">std::basic_string</a>.
|
||||||
|
|
||||||
<h2>Notes</h2>
|
<h2>Notes</h2>
|
||||||
|
<a name="1">[1]</a> Type generators are a workaround for the lack of
|
||||||
<a name="1">[1]</a> Type generators are a workaround for the lack
|
``templated typedefs'' in C++.
|
||||||
of ``templated typedefs'' in C++.
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->12 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14377" -->
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15
|
||||||
|
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14377" -->
|
||||||
|
|
||||||
|
|
||||||
<p>© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
<p>© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||||
sell and distribute this document is granted provided this copyright notice
|
sell and distribute this document is granted provided this copyright notice
|
||||||
appears in all copies. This document is provided "as is" without express or
|
appears in all copies. This document is provided "as is" without express or
|
||||||
implied warranty, and with no claim as to its suitability for any purpose.
|
implied warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
<!-- LocalWords: HTML html charset gif alt htm struct SGI namespace std libs
|
||||||
|
-->
|
||||||
|
<!-- LocalWords: InputIterator BidirectionalIterator RandomAccessIterator pdf
|
||||||
|
-->
|
||||||
|
<!-- LocalWords: typename Alexandrescu templated Andrei's Abrahams memcpy int
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- LocalWords: const OutputIterator iostream pre cpl
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- LocalWords: HTML html charset gif alt htm struct SGI namespace std libs
|
|
||||||
-->
|
|
||||||
<!-- LocalWords: InputIterator BidirectionalIterator RandomAccessIterator pdf
|
|
||||||
-->
|
|
||||||
<!-- LocalWords: typename Alexandrescu templated Andrei's Abrahams memcpy int
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
<!-- LocalWords: const OutputIterator iostream pre cpl
|
|
||||||
-->
|
|
||||||
|
Loading…
Reference in New Issue
Block a user