    <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  :: An introduction to C++ Traits</title>
        <link>https://members.accu.org/index.php/articles/442</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 #43 - Jun 2001</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/c161/">43</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+161/">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;An introduction to C++ Traits</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 June 2001 17:46:06 +01:00 or Tue, 26 June 2001 17:46:06 +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></h2>
</div>
<p>It is not uncommon to see different pieces of code that have
basically the same structure, but contain variation in the details.
Ideally we would be able to reuse the structure, and factor out the
variations. In 'C' this might be done by using function pointers,
as in the C Standard Library <tt class="function">qsort</tt>
function or in C++ by using virtual functions. Unfortunately this
differed to runtime what is known at compile time, and became with
a runtime overhead.</p>
<p>C++ introduces generic programming, with <tt class=
"literal">template</tt>s, eliminating the need for runtime binding,
but at first glance this still looks like a compromise, after all,
the same algorithm will not work optimally with every data
structure. Sorting a linked list is different to sorting an array.
Sorted data can be searched much faster than unsorted data.</p>
<p>The C++ traits technique provides an answer.</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>Think of a trait as a small object whose main purpose is to
carry information used by another object or algorithm to determine
&quot;policy&quot; or &quot;implementation details&quot;. - Bjarne Stroustrup</p>
</blockquote>
</div>
<p>Both C and C++ programmers should be familiar with <tt class=
"filename">limits.h</tt>, and <tt class="filename">float.h</tt>,
which are used to determine the various properties of the integer
and floating point types.</p>
<p>Most C++ programmers are familiar with <tt class=
"classname">std::numeric_limits</tt>, which at first glance simply
provides the same service, implemented differently. By taking a
closer look at <tt class="classname">numeric_limits</tt> we uncover
the first advantage of traits, a consistent interface.</p>
<p>Using <tt class="filename">float.h</tt>, and <tt class=
"filename">limits.h</tt>, you have to remember the type prefix and
the trait, for example, <tt class="literal">DBL_MAX</tt> contains
the &quot;maximum value&quot; trait for the <span class="type">double</span>
data type. By using a traits class such as <tt class=
"classname">numeric_limits</tt> the type becomes part of the name,
so that the maximum value for a <span class="type">double</span>
becomes <tt class="methodname">numeric_limits&lt; double
&gt;::max()</tt>, more to the point, you don't need to know which
type you need to use. For example, take this simple template
function (adapted from [<a href="#Veldhuizen">Veldhuizen</a>]),
which returns the largest value in an array:</p>
<pre class="programlisting">
template&lt; class T &gt; 
T findMax(const T const * data, 
         const size_t const numItems) { 
  // Obtain the minimum value for type T 
  T largest = 
      std::numeric_limits&lt; T &gt;::min(); 
  for(unsigned int i=0; i&lt;numItems; ++i) 
  if (data[i] &gt; largest) 
  largest = data[i]; 
  return largest; 
} 
</pre>
<p>Note the use of <tt class="classname">numeric_limits</tt>. As
you can see, where as with the C style limits.h idiom, where you
must know the type, with the C++ traits idiom, only the compiler
needs to know the type. Not only that, but <tt class=
"classname">numeric_limits</tt>, as with most traits, can be
extended to include your own custom types (such as a fixed point,
or arbitrary precision arithmetic classes) simply by creating a
specialisation of the template.</p>
<p>But I'd like to move away from <tt class=
"classname">numeric_limits</tt>, its just an example of traits in
action, and I'd like to take you through creating traits classes of
your own.</p>
<p>First lets look at one of the simplest traits classes you can
get (from <a href="http://www.boost.org" target=
"_top">boost.org</a>) and that's the <tt class=
"methodname">is_void</tt> [<a href="#boost">boost</a>] trait.</p>
<p>First, a generic template is defined that implements the default
behaviour. In this case, all but one type is <span class=
"type">void</span>, so <tt class="methodname">is_void::value</tt>
should be <tt class="literal">false</tt>, so we start with:</p>
<pre class="programlisting">
template&lt; typename T &gt; 
struct is_void{ 
  static const bool value = false;
};
</pre>
<p>Add to that a specialisation for <span class=
"type">void</span>:</p>
<pre class="programlisting">
template&lt;&gt; 
struct is_void&lt; void &gt;{ 
  static const bool value = true; 
};
</pre>
<p>And we have a complete traits type that can be used to detect if
any given type, passed in as a template parameter, is <span class=
"type">void</span>. Not the most useful piece of code on its own,
but definitely a useful demonstration of the technique.</p>
<p>Now, while fully specialised templates are useful and in my
experiance, the most common sort of trait class specialisation, I
think that it is worth quickly looking at partial specialisation,
in this case, <tt class="methodname">boost::is_pointer</tt>
[<a href="#boost">boost</a>]. Again, a default template class is
defined:</p>
<pre class="programlisting">
template&lt; typename T &gt; 
struct is_pointer{ 
  static const bool value = false; 
};
</pre>
<p>And a partial specialisation for all pointer types is added:</p>
<pre class="programlisting">
template&lt; typename T &gt; 
struct is_pointer&lt; T* &gt;{ 
  static const bool value = true; 
};
</pre>
<p>So, having got this far, how can this technique be used to solve
the lowest common denominator problem? How can it be used to select
an appropriate algorithm at compile time? This is best demonstrated
with an example.</p>
<p>First a default traits class is created, for this example we
will call it <tt class=
"classname">supports_optimised_implementation</tt>, and, other than
the name, it will be the same is the <tt class=
"classname">is_void</tt> example. Next the default algorithm is
implemented, inside a templated <tt class=
"classname">algorithm_selector</tt>, in this example the <tt class=
"classname">algorithm_selector</tt> template is parameterised with
a <span class="type">bool</span>, but in situations where a number
of algorithms could be appropriate it could just as easily be
parameterised with an <span class="type">int</span>, or an
<span class="type">enum</span>. In this case <tt class=
"literal">true</tt> will mean &quot;use optimised algorithm in
object&quot;.</p>
<pre class="programlisting">
template&lt; bool b &gt; 
struct algorithm_selector { 
  template&lt; typename T &gt; 
  static void implementation( T&amp; object ) 
  { 
//implement the alorithm operating on &quot;object&quot; here 
  } 
};
</pre>
<p>Next a specialisation of <tt class=
"classname">algorithm_selector</tt> is added which, in this case,
passes the responsibility for implementing the algorithm back to
the author of the object being operated on, but could well
implement a second version of the operation itself.</p>
<pre class="programlisting">
template&lt;&gt; 
struct algorithm_selector&lt; true &gt; { 
  template&lt; typename T &gt; 
  static void implementation( T&amp; object )   { 
    object.optimised_implementation(); 
  } 
};
</pre>
<p>Then we write the generic function that the end user of your
algorithm will call, note that it in turn calls <tt class=
"classname">algorithm_selector</tt>, parameterised using our
<tt class="classname">supports_optimised_implementation</tt> traits
class:</p>
<pre class="programlisting">
template&lt; typename T &gt; 
void algorithm( T&amp; object ) { 
  algorithm_selector&lt; supports_optimised_implementation&lt; T &gt;::value &gt;::implementation(object); 
}
</pre>
<p>Now all that's left to do is test it against a class that
doesn't support the feature ( <tt class="literal">class
ObjectA{};</tt> ), and a class that does:</p>
<pre class="programlisting">
class ObjectB { 
public: 
  void optimised_implementation() { 
//... 
  } 
};
</pre>
<p>specialisation of <tt class=
"classname">supports_optimised_implementation</tt> trait for
<tt class="classname">ObjectB</tt></p>
<pre class="programlisting">
template&lt;&gt; 
struct 
supports_optimised_implementation&lt; ObjectB &gt; { 
  static const bool value = true; 
};
</pre>
<p>Finally, instantiate the templates:</p>
<pre class="programlisting">
int main(int argc, char* argv[]) { 
  ObjectA a; 
  algorithm( a ); 
// calls default implementation 
  ObjectB b; 
  algorithm( b ); 
// calls 
// ObjectB::optimised_implementation(); 
  return 0; 
}
</pre>
<p>And that's it. Hopefully you can now &quot;wow&quot; your friends and
colleague with your in-depth understanding of the c++ traits
concept. :)</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e212" id="d0e212"></a>Notes</h2>
</div>
<p>It should be noted that the examples in this article require a
cutting edge, standard compliant, compiler. For example, MSVC++ 6.0
does not support static constants, and will balk on:</p>
<pre class="programlisting">
static const bool value = false;
</pre>
<p>This particular problem can be worked around by using an enum in
its place, i.e:</p>
<pre class="programlisting">
enum { value = false }; 
</pre>
<p>Please contact your compiler vendor for appropriate work arounds
and bug fixes for your platform.</p>
<p>With thanks to Mark Radford, Gavin Buttimore, Martin Lester,
Russ Williams &amp; Francis Irving.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="Alexandrescu2" id=
"Alexandrescu2"></a>References and Further Reading</h2>
</div>
<div class="bibliomixed"><a name="Myers" id="Myers"></a>
<p class="bibliomixed">[Myers] <span class="citetitle"><i class=
"citetitle">Traits: a new and useful template technique</i></span>
by Nathan C. Myers.</p>
</div>
<div class="bibliomixed"><a name="Veldhuizen" id="Veldhuizen"></a>
<p class="bibliomixed">[Veldhuizen] <span class=
"citetitle"><i class="citetitle">Using C++ Trait Classes for
Scientific Computing</i></span> by Todd Veldhuizen.</p>
</div>
<div class="bibliomixed"><a name="boost" id="boost"></a>
<p class="bibliomixed">[boost] <span class="bibliomisc"><a href=
"http://www.boost.org" target="_top">boost.org</a></span>'s
<span class="bibliomisc"><tt class=
"literal">type_traits</tt></span>.</p>
</div>
<div class="bibliomixed"><a name="Maddock" id="Maddock"></a>
<p class="bibliomixed">[Maddock] <span class="citetitle"><i class=
"citetitle">C++ Type Traits</i></span> by John Maddock &amp; Steve
Cleary, <span class="citetitle"><i class="citetitle">Dr Dobb's
Journal</i></span> #317</p>
</div>
<div class="bibliomixed"><a name="Alexandrescu1" id=
"Alexandrescu1"></a>
<p class="bibliomixed">[Alexandrescu1] <span class=
"citetitle"><i class="citetitle">Traits: The else-if-then of
Types</i></span> - Andrei Alexandrescu</p>
</div>
<div class="bibliomixed">
<p class="bibliomixed"><span class="citetitle"><i class=
"citetitle">Traits on Steroids</i></span> - Andrei Alexandrescu</p>
</div>
<div class="bibliomixed"><a name="Sutter" id="Sutter"></a>
<p class="bibliomixed">[Sutter] Guru of the Week #71 <span class=
"citetitle"><i class="citetitle">Inheritance Traits?</i></span> -
Herb Sutter</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
