    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Template Titbit - A Different Perspective</title>
        <link>https://members.accu.org/index.php/articles/408</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #48 - Apr 2002</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c197/">48</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-197/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+197/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Template Titbit - A Different Perspective</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 April 2002 17:46:09 +01:00 or Fri, 26 April 2002 17:46:09 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a>Background</h2>
</div>
<p>Oliver Schoenborn's article, &quot;Tiny Template Tidbit&quot;, in Overload
47 illustrates some of the wonderful things you can do with
templates. I particularly liked the way it described the thought
processes Oliver went through when designing some curve-fitting
software and his clear explanation of the problem he set himself.
Whilst reading an earlier draft of &quot;Tidbit&quot; a slightly different
solution occurred to me, which I shared with Oliver before
publication. With the deadline approaching there wasn't much time
for discussion, so we agreed that I should write up those ideas
that seemed interesting, but that were not strictly relevant to
Oliver's article.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e23" id="d0e23"></a>Recap</h2>
</div>
<p>The &quot;Tidbit&quot; article used a <tt class="function">fitCurve()</tt>
function template to illustrate the techniques of interest:</p>
<pre class="programlisting">
template &lt;class CoordContainer&gt;
Curve fitCurve(
          const CoordContainer&amp; coords) {
  // ...
  // set coord1 to first Coord in coords
  // set coord2 to second Coord in coords
  Coord c = coord1 + coord2;
  // ...
}
</pre>
<p>The challenge was to make this template work for containers
whose elements are: points, objects that contain a point, or
pointers to any of those types.</p>
<p>Oliver called his point class &quot;Coord&quot;. The key to his solution
was a <tt class="function">getCoord()</tt> function template that
returned the <tt class="classname">Coord</tt> corresponding to a
given container element. Different specialisations of <tt class=
"function">getCoord()</tt> were defined for different types of
element.</p>
<pre class="programlisting">
// General function template
template &lt;class PntClass&gt; inline
const Coord&amp; getCoord(const PntClass&amp; p)
{ return p.coords; }

// Partial specialization for pointers
// to things
template &lt;class PntClass&gt;
const Coord&amp; getCoord(const PntClass* p)
{ return p-&gt;coords; }

// Complete specialization for Coord
inline
const Coord&amp; getCoord(const Coord&amp; p)
{ return p; }

// Complete specialization for pointer
// to Coord
inline
const Coord&amp; getCoord(const Coord* p)
{ return *p; }
</pre>
<p>This version of the <tt class="function">getCoords()</tt>
function template covers element types that are: <tt class=
"classname">Coord</tt>, pointer to <tt class=
"classname">Coord</tt>, something containing a 'coords' data
member, and pointer to something containing a 'coords' data member.
It doesn't cover elements whose <tt class="classname">Coord</tt> is
accessed via a member function. For this, a <tt class=
"function">getData()</tt> function template was introduced and the
appropriate <tt class="function">getCoord()</tt> specialisations
were re-written in terms of <tt class=
"function">getData()</tt>.</p>
<pre class="programlisting">
template &lt;class PntClass&gt;
const Coord&amp; getCoord(const PntClass&amp; v) {
  return getData(v, &amp;PntClass::coords);
}

// partial specialization for pointers
template &lt;class PntClass&gt;
const Coord&amp; getCoord(const PntClass* v) {
  return getData(*v, &amp;PntClass::coords );
}

template &lt;class PntClass&gt;
inline
const Coord&amp; getData(const PntClass&amp; pp,
                     Coord PntClass::* dd) {
  return pp.*dd;
}

template &lt;class PntClass&gt;
inline
const Coord&amp; getData(const PntClass&amp; pp,
                     const Coord&amp; (PntClass::* mm)() const) {
  return (pp.*mm)();
}
</pre>
<p>This is a neat and, as far as I know, original idea that makes
it possible to use either data members or member functions
interchangeably in generic functions.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e75" id=
"d0e75"></a>Suggestions</h2>
</div>
<p>I made three suggestions:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>pass a pair of iterators to the curve-fitting function rather
than a const reference to a container,</p>
</li>
<li>
<p>use a traits class to extract the co-ordinates from objects of
arbitrary type and</p>
</li>
<li>
<p>use a curve-fitting function with &quot;external state&quot;.</p>
</li>
</ol>
</div>
<p>Oliver liked the traits idea, but found it didn't give him what
he wanted. And, from his perspective, the other two suggestions
just weren't relevant to the problem at hand. After some thought I
realised that it was all a question of your point-of-view. As
Kevlin Henney often points out, the solution to a problem depends
on the context. Oliver had chosen the context of a specific
project; I was thinking of a general-purpose library.</p>
<p>Let's look at these ideas in a bit more detail.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e94" id="d0e94"></a>Iterator Range
or Container?</h2>
</div>
<p>Passing a pair of iterators to the <tt class=
"function">fitCurve()</tt> function is more general than passing a
container, but it's often less convenient for the calling code. An
iterator range allows containers without <tt class=
"methodname">begin()</tt> and <tt class="methodname">end()</tt>
functions to be used (such as arrays) and makes it easy to fit a
curve to a subset of the points in a given container. On the other
hand, it means passing two parameters instead of one.</p>
<p>For a general-purpose library flexibility is very important.
Oliver's project doesn't need that much flexibility, so ease-of-use
dominates the trade-off. Context matters here.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e110" id="d0e110"></a>Traits
Classes or Function Templates?</h2>
</div>
<p>The &quot;Tidbit&quot; article shows how to write some generic components
that support containers in which the element type is in one of four
fairly general categories. In that article Oliver makes the point
that this may not be general enough for a library and I agree. What
I had in mind was a traits class template that defines a mechanism
for accessing the co-ordinates of a point class. The following
template and partial specialisation illustrates the idea for points
in the X,Y plane.</p>
<pre class="programlisting">
// The general version of the point
// traits class.
template&lt;typename point_type&gt;
struct point_traits {
  static double x(const point_type&amp; p) {
    return p.x();
  }
  static double y(const point_type&amp; p) {
    return p.y();
  }
};

// A partial specialisation of the point
// traits class for pointers.
template&lt;typename point_type&gt;
struct point_traits&lt;point_type*&gt; {
  static double x(point_type* p) {
    return p-&gt;x();
  }
  static double y(point_type* p) {
    return p-&gt;y();
  }
};
</pre>
<p>The general version of the template provides co-ordinate access
functions for point classes having member functions <tt class=
"methodname">x()</tt> and <tt class="methodname">y()</tt>. The
partial specialisation does the same for pointers to classes with
<tt class="methodname">x()</tt> and <tt class="methodname">y()</tt>
member functions. For any other type of point class the user would
have to define a further specialisation of the traits template. For
example:</p>
<pre class="programlisting">
// A complete specialisation of the point
// traits class for POD_Point.
struct POD_Point { double x, y; };

template&lt;&gt;
struct point_traits&lt;POD_Point&gt; {
  static double x(const POD_Point&amp; p) {
    return p.x;
  }
  static double y(const POD_Point&amp; p) {
    return p.y;
  }
};
</pre>
<p>The <tt class="classname">point_traits&lt;&gt;</tt> member
functions are similar to Oliver's <tt class=
"function">getCoord()</tt> functions. They are <span class=
"emphasis"><em>template</em></span> functions and their purpose is
to extract information from some sort of point object. They are
used in the curve fitting algorithm in a similar way. My
implementation of a least-squares line algorithm, for example,
contains the following lines:</p>
<pre class="programlisting">
template&lt;typename point_type&gt;
void add(point_type point) {
  double x = point_traits&lt;point_type&gt;::x(point);
  double y = point_traits&lt;point_type&gt;::y(point);
  // ...
}
</pre>
<p>In principle, the traits member functions could be implemented
in terms of another function template, like Oliver's <tt class=
"function">getData()</tt>, which would make it possible to handle
both data members and member functions out of the box. I prefer not
to do this, though. The traits mechanism is general enough to be
used with arbitrary types of point object and the inconvenience of
having to define a traits specialisation for point classes without
the <tt class="methodname">x()</tt> and <tt class=
"methodname">y()</tt> access functions is small. In fact, the lack
of support for data members could even be seen as an advantage - it
should encourage the use of fully-fledged, properly encapsulated
point classes. More importantly, though, I wouldn't want the name
of a member of a class in the client code to appear in my library
functions the way 'coords' appears in Oliver's <tt class=
"function">getCoord()</tt> functions. If we were to do this in a
general purpose library what would we call the member? 'coords',
'point', 'm_2Dpoint', 'xyPoint_', &hellip; The list is endless!</p>
<p>Of course, if you are working on a project that already has to
deal with a variety of point classes, some of which use data
members, the need for extra traits specialisations could be a
nuisance. But, then again, how many different point classes do you
want to use in the same application? Not many, I think.</p>
<p>Once again, context matters.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e164" id="d0e164"></a>External or
Internal Algorithm State?</h2>
</div>
<p>The only curve fitting algorithm I am familiar with is the
least-squares line and its 3-dimensional cousin, the leastsquares
plane. In fact, the least-squares line can be defined as
follows:</p>
<div class="informaltable">
<table border="1" cellspacing="0">
&lt;colgroup&gt;
&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody&gt;
<tr>
<td>Given a set of points (x<sub>i</sub>,y<sub>i</sub>), where i =
1..n, the least-squares line through those points is given by y =
mx + c, where: m = ( n&sum; x<sub>i</sub>y<sub>i</sub> - &sum;
x<sub>i</sub>&sum; y<sub>i</sub> ) / ( n&sum;
x<sub>i</sub>x<sub>i</sub> - &sum; x<sub>i</sub>&sum; x<sub>i</sub>
) and c = ( &sum; y<sub>i</sub> - m&sum; x<sub>i</sub> ) / n</td>
</tr>
&lt;/tbody&gt;
</table>
</div>
<p>A straightforward implementation of this formula in code
involves four totals (&sum; x<sub>i</sub>, &sum; y<sub>i</sub>,
&sum; x<sub>i</sub>x<sub>i</sub> and &sum;
x<sub>i</sub>y<sub>i</sub>) and a point count. Old fashioned C++
code might look like this&hellip;</p>
<pre class="programlisting">
// Initial data.
struct Point {double x, y;};
Point point[20] = { ... };
unsigned n = 0;
double x_sum = 0, y_sum = 0,
       xx_sum = 0, xy_sum = 0;

// Accumulate sums for each (x,y)
// point...
for (int i = 0; i &lt; 20; ++i) {
  ++n;
  x_sum += point[i].x;
  y_sum += point[i].y;
  xx_sum += point[i].x * point[i].x;
  xy_sum += point[i].x * point[i].y;
}

// Calculate slope and offset.
double m = (n * xy_sum - x_sum * y_sum)
         / (n * xx_sum - x_sum * x_sum);
double c = (y_sum - m * x_sum) / n;
</pre>
<p>The algorithm reminded me of the standard accumulate function,
so my first thought for a least-squares function in the modern
style was modelled on <tt class=
"function">std::accumulate()</tt>.</p>
<pre class="programlisting">
// A line in the X,Y plane.
class line;

namespace least_squares {
  // The current state of the least-
  // squares line algorithm.
  struct state {
    state() : n(0), x_sum(0), y_sum(0),
              xx_sum(0), xy_sum(0) {}
    operator line() { ... }
    // ...
    unsigned n;
    double x_sum, y_sum,
           xx_sum, xy_sum;
  };

  // Fit a least-squares line to the
  // (x,y) points in [first,last)
  template&lt;typename iterator_type&gt;
  state fit(iterator_type first,
            iterator_type last,
            state = state());
}
</pre>
<p>The curve fitting function is given an initial state and returns
a new state after accumulating points in the iterator range
[first,last). This is what I have called a &quot;function with external
state&quot;. The default initial state corresponds to no points
accumulated.</p>
<p>The state class has a conversion operator that provides an
implicit conversion to a line. The combination of external state
and conversion operator makes it possible to fit a least-squares
line in several stages.</p>
<pre class="programlisting">
using least_squares::state;
using least_squares::fit;

state algorithm_state =
             fit(point, point + 10);

line best_fit_line =
             fit(point + 10, point + 20,
                 algorithm_state);
</pre>
<p>Unfortunately, there are several unpleasant features in this
design. The state class has public data and an implicit conversion
operator. Passing the state into and out of the <tt class=
"function">fit()</tt> function by value leads to unnecessary
copying. And the simple case of fitting a least-squares line to all
the points in a container carries the excess intellectual baggage
of the state object.</p>
<p>In thinking about these points I finally settled on a design
offering two interfaces that differ in generality and convenience.
The less general/more convenient interface is provided as a single
template function, <tt class=
"function">least_squares::fit()</tt>.The more general/less
convenient interface is provided as two classes: <tt class=
"classname">least_squares::state</tt> and <tt class=
"classname">least_squares::add_point</tt>. The point traits idea
has been retained to allow the underlying implementation to adapt
to different point classes.</p>
<pre class="programlisting">
// Summary of least-squares components
// for the X,Y plane.
class point;
class line;
template&lt;typename T&gt; struct point_traits;

namespace least_squares {
  // General interface.
  class add_point;
  class state;
  // Convenient interface.
  template&lt;typename iterator_type&gt;
  line fit(iterator_type first,
           iterator_type last);
}
</pre>
<p>The state class is at the heart of this new design. It now
properly encapsulates its data and provides a minimal interface. It
has just two member functions: one to add a point and one to create
a line.</p>
<pre class="programlisting">
// The state of the least-squares
// line algorithm.
class least_squares::state {
public:
  state();
  template&lt;typename point_type&gt;
  void add(point_type point);
  ::line line();
private:
  unsigned n;
  double x_sum, y_sum, xx_sum, xy_sum;
};
</pre>
<p>The <tt class="function">add()</tt> function uses the point
traits template to extract individual co-ordinates from each point,
calculates new values for the four totals and increments the point
count.</p>
<pre class="programlisting">
template&lt;typename point_type&gt;
void least_squares::state::add(
                            point_type point) {
  ++n;
  double x =
          point_traits&lt;point_type&gt;::x(point);
  double y =
          point_traits&lt;point_type&gt;::y(point);
  x_sum += x;
  y_sum += y;
  xx_sum += x * x;
  xy_sum += x * y;
}
</pre>
<p>The <tt class="function">line()</tt> function calculates the
slope and offset of the leastsquares line and returns a line
object. At least two points must have been accumulated before this
function is called. The pre-condition is checked using <tt class=
"function">assert()</tt>, here; throwing an exception or the use of
a policy class might be more appropriate for a real library.</p>
<pre class="programlisting">
::line least_squares::state::line() {
  assert(n &gt; 1);
  double m = (n * xy_sum - x_sum * y_sum)
           / (n * xx_sum - x_sum * x_sum);
  double c = (y_sum - m * x_sum) / n;
  return ::line(m, c);
}
</pre>
<p>The state class actually provides everything we need to find the
least-squares line for a set of points. On its own, however, it is
slightly inconvenient to use. The programmer using the curve
fitting library needs to iterate through the points, either by
writing a loop or by passing a suitable function object to
<tt class="function">std::for_each()</tt>. The <tt class=
"classname">add_point</tt> class provided by the library is just
the right sort of function object for <tt class=
"function">std::for_each()</tt>. Its function call operator simply
calls the <tt class="methodname">state:add()</tt> function.</p>
<pre class="programlisting">
class least_squares::add_point {
public:
  add_point(state&amp; s) : algorithm_state(s) {}
  template&lt;typename point_type&gt;
  void operator() (point_type point) {
    algorithm_state.add(point);
  }
private:
  state&amp; algorithm_state;
};
</pre>
<p>With this convenience class, even the general interface to the
least-squares algorithm becomes quite easy to use, as the following
example shows.</p>
<pre class="programlisting">
using std::foreach;
using least_squares::state;
using least_squares::add_point;
// Find the line that best fits
// point[0]..point[19].
state best_fit_data;
for_each(point, point + 20,
         add_point(best_fit_data));
line best_fit_line = best_fit_data.line();
</pre>
<p>The alternative interface just wraps up these three lines of
code in a template function.</p>
<pre class="programlisting">
template&lt;typename iterator_type&gt;
line least_squares::fit(iterator_type first,
                        iterator_type last) {
  state algorithm_state;
  std::for_each(first, last,
                add_point(algorithm_state));
  return algorithm_state.line();
}
</pre>
<p>The previous curve fitting example can now be re-written as a
one-liner, which I leave as an exercise for the interested
reader.</p>
<p>So, my answer to the external/internal state question is,
&quot;Both&quot;. The general interface uses external state in the form of an
add_point function object; the convenient interface keeps the
algorithm state entirely within the <tt class="function">fit()</tt>
function. Once again, context matters, and this time the library
can not guess which is the more important.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e316" id="d0e316"></a>Final
Thoughts</h2>
</div>
<p>The curve-fitting code presented here illustrates how Object-
Oriented Programming and Generic Programming can work together. The
<tt class="classname">least_squares::state</tt> class obeys the
principles of OOP; the <tt class="function">fit()</tt> function is
a generic algorithm. Together they provide a safe, flexible and
efficient software component.</p>
<p>The difference between Oliver's code and mine comes down to the
context of the problem. It's like spelling. The dictionary in my
version of Microsoft Word says &quot;tidbit&quot; is an error and offers
&quot;titbit&quot; as the correct spelling. My Chambers dictionary has both
spellings. Context matters!</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
