    <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 Metaprogramming</title>
        <link>https://members.accu.org/index.php/articles/424</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 #46 - Dec 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/c158/">46</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+158/">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 Metaprogramming</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 December 2001 16:46:08 +00:00 or Wed, 26 December 2001 16:46:08 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
<h3>make your compiler work for you</h3>
</div>
<p>What is Template Metaprogramming? The prefix meta- is usually
used to indicate an additional level of abstraction: metadata is
information about data. Similarly, metaprogramming is writing
programs about programs. The emerging technique of template
metaprogramming takes advantage of C++ templates to write programs
that manipulate themselves or other programs at compile time.</p>
<p>Template metaprogramming is both a curiosity and a powerful
optimisation method. The curiosity is that a standard C++ compiler
is a Turing-complete interpreter for a subset of C++. In theory,
any computable problem can be solved at compile time without ever
executing compiled code; in practice achievable results are limited
by inefficiencies of the system and details of the
compiler<sup>[<a name="d0e26" href="#ftn.d0e26" id=
"d0e26">1</a>]</sup>. Metaprogramming can facilitate increased
performance by computing performance-critical results at compile
time or using compile-time logic to choose the best algorithm for
the job.</p>
<p>I became interested in the subject of template metaprogramming
after reading two recently published books: <span class=
"emphasis"><em>Andrei Alexandrescu's Modern C++ Design</em></span>
<a href="#Alexandrescu">[Alexandrescu]</a>, and <span class=
"emphasis"><em>Czarnecki and Eisenecker's Generative
Programming</em></span> <a href="#Czarnecki-">[Czarnecki-]</a>. I
highly recommend both these books; they will remind you of the
richness of the C++ language.</p>
<p>The basic tools of metaprogramming consist of constructions that
should be familiar to most C++ programmers: compile-time constants,
typedefs, template specialization, and recursive templates. These
are enough to provide both a looping construction (recursive
templates) and a conditional (template specialization), which are,
in turn, enough for a Turing-complete language.</p>
<p>The mechanics of metaprogramming may require a readjustment from
the regular C++ programmer, since the C++ metaprogramming
sub-language resembles a dynamically-typed functional language.
However, with a good grasp of recursion, a few hints from
functional programming languages, and a will to learn, the area can
be quickly understood.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e48" id=
"d0e48"></a>Metafunctions</h2>
</div>
<p>One of the basic metaphors of metaprogramming is what I call
template-is-function. Template-is-function is characterized by a
template struct with an enum or typedef as a return value.
Czarnecki and Eisenecker call such structs &quot;metafunctions&quot; <a href=
"#Czarnecki-">[Czarnecki-]</a>. An example metafunction to compute
the square of N is:</p>
<pre class="programlisting">
template&lt;int n&gt;
struct Sqr {enum { RET = n*n }; };
</pre>
<p>And it is used like this:</p>
<pre class="programlisting">
std::cout &lt;&lt; Sqr&lt;10&gt;::RET &lt;&lt; std::endl;
</pre>
<p>Note that the example above and those that follow use the &quot;enum
hack&quot; to define integer constants. This is a workaround for
compilers which do not support the standard C++ feature of
initialization of static constants inside the class definition, as
shown below<sup>[<a name="d0e64" href="#ftn.d0e64" id=
"d0e64">2</a>]</sup>:</p>
<pre class="programlisting">
//alternative implementation
template&lt;int n&gt;
struct Sqr {static const int RET = n*n; };
</pre>
<p>Several parts of metafunctions are analogous to those of
ordinary functions. Here is a mapping from the concepts of ordinary
functions to those of metafunctions:</p>
<div class="literallayout">
<p>function             -&gt;     templated type (struct or
class)<br>
function arguments   -&gt;     template arguments<br>
function return(s)   -&gt;     public enums/static
constants/typedefs</p>
</div>
<p>There are several things to note here. First, it is often
convenient to use structs rather than classes to avoid typing the
<tt class="literal">public:</tt> declaration. However, if our
metafunction has something to hide (intermediate implementation
details), we can use a class and encapsulate those details. Second,
it is possible for a metafunction to have multiple return values. I
use Czarnecki and Eisenecker's convention of naming a single return
value <tt class="literal">::RET</tt> (for return). Another popular
name is <tt class="literal">::value</tt>, which is used by Andrei
Alexandrescu in <span class="emphasis"><em>Modern C++
Design</em></span> [<a href="#Alexandrescu">Alexandrescu</a>], as
well as the boost libraries [<a href="#Boost">Boost</a>].
Regardless of the particular convention, it is often important to
have consistently named returns, as we will see.</p>
<p>Here is another metafunction that computes N factorial:</p>
<pre class="programlisting">
template&lt;int n&gt; 
struct Factorial {enum {RET = n * Factorial&lt;n-1&gt;::RET };  };
</pre>
<p>By itself, this would result in infinite recursion, so we add a
base case through template specialization:</p>
<pre class="programlisting">
template&lt;&gt;
struct Factorial&lt;0&gt; {enum {RET = 1 };  };
</pre>
<p>This example demonstrates two central elements of
metaprogramming: looping using recursive templates, and
conditionals using template specialization. As an exercise, you
might write a metafunction to compute the nth member of the
Fibonacci series.</p>
<p>So far this should be pretty comfortable territory. Now prepare
yourself for a dark journey to the land of the angle brackets as we
explore compile-time data structures.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e106" id=
"d0e106"></a>Metaobjects<sup>[<a name="d0e109" href="#ftn.d0e109"
id="d0e109">3</a>]</sup></h2>
</div>
<p>To simulate collections and other objects at compile time we
will take a hint from a functional language, in this case, Lisp.
The basic data structure in Lisp is called a <tt class=
"literal">cons</tt>, which is more or less the equivalent of
<tt class="literal">std::pair</tt>. A <tt class="literal">cons</tt>
has two members, <tt class="literal">car</tt>, which is the head,
and <tt class="literal">cdr</tt>, which is the tail<sup>[<a name=
"d0e129" href="#ftn.d0e129" id="d0e129">4</a>]</sup>. I have
followed Czarnecki and Eisenecker by adopting the more descriptive
<tt class="literal">Head</tt> and <tt class="literal">Tail</tt>. We
can form lists, trees, and other useful data structures by creating
<tt class="literal">cons</tt>es which themselves contain <tt class=
"literal">cons</tt>es. We terminate these data structures with a
special empty value, <tt class="literal">Nil</tt>. Our
metaprogramming list basics are:</p>
<pre class="programlisting">
struct Nil {
  typedef Nil Head;
  typedef Nil Tail;
};
template&lt;class Head_, class Tail_=Nil&gt;
struct Cons {
  typedef Head_ Head;
  typedef Tail_ Tail;
};
</pre>
<p>To enable us to hold integers in <tt class=
"literal">cons</tt>es, we'll define:</p>
<pre class="programlisting">
template &lt;int n&gt; 
struct Int {enum {RET = n }; };
</pre>
<p>Now we can represent the list 3, 1, 2, 4 as:</p>
<pre class="programlisting">
Cons&lt;Int&lt;3&gt;, Cons&lt;Int&lt;1&gt;, Cons&lt;Int&lt;2&gt;, Cons&lt;Int&lt;4&gt;, Nil&gt; &gt; &gt; &gt;
</pre>
<p>See what I mean about angle brackets?</p>
<p>Simulating <tt class="literal">cons</tt> in C++ metaprogramming
demonstrates the metaphor I call &quot;template-is-object.&quot; Multiple
typedefs or enums in a struct work like the members of a C++
object. Here is the mapping from the concepts of ordinary objects
to those of metaobjects:</p>
<div class="literallayout">
<p>object                     -&gt;   templated type (struct or
class)<br>
constructor arguments      -&gt;   template arguments<br>
methods/member variables   -&gt;   enums/static
constants/typedefs</p>
</div>
<p>The template-is-object metaphor works somewhat less well than
template-is-function because in metaprogramming there is no way to
modify member variables. Rather than true variables, functional
programming has symbolic names for values. If a new value is
needed, a new name must be introduced [<a href=
"#Czarnecki-">Czarnecki-</a>].</p>
<p>There are many interesting metafunctions that could be written
to operate on lists made up of conses, e.g.,</p>
<pre class="programlisting">
//metafunction to compute the length of a list made up of conses
template&lt;class List&gt;
struct Length {enum {RET = 1 + Length&lt;typename List::Tail&gt;::RET}; };
template&lt;&gt;
struct Length&lt;Nil&gt; {enum {RET = 0 }; };
//metafunction to append an object to the end of a list
template&lt;class Elt, class List&gt;
struct Append1 { 
typedef Cons&lt;typename List::Head, Append1&lt;Elt, typename List::Tail&gt;::RET&gt; RET;
};
template&lt;class Elt&gt; struct Append1&lt;Elt, Nil&gt; { typedef Elt RET; }
</pre>
<p>A quick glance through an introductory Lisp book shows the
functions <tt class="literal">member</tt>, <tt class=
"literal">nth</tt>, and <tt class="literal">union</tt> as
interesting candidates for metafunction-writing exercises [<a href=
"#Graham">Graham</a>]. If nothing else, your excursion into
metaprogramming will teach you how to use the <tt class=
"literal">typename</tt> keyword<sup>[<a name="d0e199" href=
"#ftn.d0e199" id="d0e199">5</a>]</sup>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e206" id="d0e206"></a>How Many
Queens are Too Many?</h2>
</div>
<p>Knowing that the best way to learn is by doing, I set out to
solve an example problem with metaprogramming, N queens. For those
who are not familiar with the problem, the task is to find a
placement of N queens on an N x N chessboard so that none of them
is attacked by the other queens. This is a generalization of the
8-queens problem, which uses a standard chessboard.</p>
<p>The first task was to develop an ordinary solution to the
problem. After some tinkering, I came up with:</p>
<pre class="programlisting">
//represent a queen by its row and column
struct Queen {
  Queen(int r, int c) : row(r), col(c) { }
  int row;
  int col;
};

//determine whether newQueen would attack any of queens check for horizontal
// (rowdiff==0), vertical (coldiff==0), and diagonal attacks (rowdiff==coldiff)
bool hasConflicts(Queen newQueen, std::list&lt;Queen&gt; queens){
  for (std::list&lt;Queen&gt;::iterator ii=queens.begin(); ii!=queens.end(); ++ii) {
    int rowdiff = abs(ii-row - newQueen.row);
    int coldiff = abs(ii-col - newQueen.col);
    if (rowdiff==0 || coldiff==0 || rowdiff==coldiff)
      return true;
  }
  return false;
}

//display a solution (a list of queens) as pairs of coordinates separated by semicolons
void printSolution(std::list&lt;Queen&gt; queens){
  for(std::list&lt;Queen&gt;::iterator ii=queens.begin(); ii!=queens.end(); ++ii) {
    std::cout &lt;&lt; &quot;(&quot; &lt;&lt; ii-row &lt;&lt; &quot;,&quot; &lt;&lt; ii-col &lt;&lt; &quot;);&quot;;
  }
  std::cout &lt;&lt; std::endl;
}

//place a Queen on the &quot;board&quot; by adding to the list queens
//Recursively places the next queen and prints a solution if it exists 
void placeQueen(int N, int row, int col, std::list&lt;Queen&gt; queens) {
//try the next column for additional solutions
  if (col  N-1)
    placeQueen(N, row, col+1, queens);
//if there is no conflict, attempt another queen in the next row
  if (!hasConflicts(Queen(row, col), queens)) {
    queens.push_back(Queen(row, col));
//if we have not yet reached a full solution, place another
//queen; else, print the solution
    if (row  N-1)
      placeQueen(N, row+1, 0, queens);
    else
      printSolution(queens);
  }
}

//reads the problem size from the command line and prints any solutions
int main(int argc, char* argv[]) {
  int N = 8;
  if (argc &gt; 1)
    N = atoi(argv[1]);
  placeQueen(N, 0, 0, std::list&lt;Queen&gt;());
}
</pre>
<p>This prints the solutions in a not-so-user-friendly format to
<tt class="literal">stdout</tt>. A good test is the number of
solutions (for 8 queens it should be 92). We can check by piping
the output into the Unix &quot;wc&quot; utility, which counts lines when
given the -l option.</p>
<pre class="programlisting">
jwalker@avakkai $a.out 8 | wc -l
  92
</pre>
<p>Looks good. Now to translate it to a metaprogram. The <tt class=
"literal">Queen</tt> struct becomes:</p>
<pre class="programlisting">
template&lt;int r, int c&gt;
struct Queen {
  enum { row = r };
  enum { col = c };
};
</pre>
<p>To implement <tt class="literal">HasConflicts</tt>, we will need
an abs equivalent:</p>
<pre class="programlisting">
template&lt;int&gt; n
struct Abs {enum { RET = n &lt; 0 ? -n : n }; };
</pre>
<p>We can replace the for loop in <tt class=
"literal">hasConflicts</tt> with recursion:</p>
<pre class="programlisting">
template&lt;class Queen, class QueenList&gt;
class HasConflicts {
  typedef typename QueenList::Head Head;
  enum { coldiff = Abs&lt;Queen::col - Head::col&gt;::RET };
  enum { rowdiff = Abs&lt;Queen::row - Head::row&gt;::RET };
public:
  enum {RET = coldiff==0 || rowdiff==0 || coldiff == rowdiff ?
    true : HasConflicts&lt;Queen, typename QueenList::Tail&gt;::RET
  };
};
template&lt;class Queen&gt;
class HasConflicts&lt;Queen, Nil&gt; {
public:
  enum { RET = false };
};
</pre>
<p>Notice that the implementation details are hidden by making them
<tt class="literal">private</tt>.</p>
<p>A compile-time if statement will make implementing <tt class=
"literal">placeQueen</tt> much easier. Czarnecki and Eisenecker
provide this implementation using partial specialization (as well
as another which does not require partial specialization) [<a href=
"#Czarnecki-">Czarnecki-</a>]:</p>
<pre class="programlisting">
template&lt;bool condition, class Then, class Else&gt;
struct IF {typedef Then RET;};
template&lt;class Then, class Else&gt;
struct IF&lt;false, Then, Else&gt; {typedef Else RET; };
</pre>
<p>As Czarnecki and Eisenecker explain, when using this
compile-time if statement, it is important to move as much
evaluation outside the template arguments as possible. Otherwise,
infinite template recursion could result. That is, instead of:</p>
<pre class="programlisting">
typedef typename IF&lt;n==0, F&lt;n&gt;::RET, G&lt;n&gt; &gt;::RET::RET RET;
</pre>
<p>The evaluation of <tt class="literal">::RET</tt> in the
<tt class="literal">Then</tt> or <tt class="literal">Else</tt>
parts should be delayed:</p>
<pre class="programlisting">
typedef typename IF&lt;n==0, F&lt;n&gt;, G&lt;n&gt; &gt;::RET::RET RET;
</pre>
<p>This explains the need for a consistent naming scheme for
metafunction returns. If <tt class="literal">F&lt;&gt;</tt> and
<tt class="literal">G&lt;&gt;</tt> used different names for their
return values, it would not be possible to move the evaluation
outside <tt class="literal">IF&lt;&gt;</tt>. Of course, there will
be occasions when it is inconvenient to have the same name for
return values. Consider a case where we have received a list in the
template parameter <tt class="literal">OldList</tt> and wish to
conditionally append a value to it:</p>
<pre class="programlisting">
//won't compile
typedef typename IF&lt;n==0, OldList, Append1&lt;Int&lt;n&gt;, OldList &gt;::RET::RET RET;
</pre>
<p>Here the problem is that there is no typedef <tt class=
"literal">RET</tt> in <tt class="literal">OldList</tt> (which is
just a <tt class="literal">cons</tt>). To solve this problem, we
can use an extra level of indirection with a &quot;template adapter.&quot; In
the case of <tt class="literal">con</tt>s, this should simply make
the structure available as the typedef <tt class=
"literal">RET</tt>. We will name the metafunction <tt class=
"literal">Identity</tt>, after the Lisp function which performs the
same operation.</p>
<pre class="programlisting">
template&lt;class Obj&gt; struct Identity {typedef Obj RET; };
</pre>
<p>Now the example above could correctly be written as:</p>
<pre class="programlisting">
typedef typename IF&lt;n==0, Identity&lt;OldList&gt;, Append1&lt;Int&lt;n&gt;, OldList &gt;::RET::RET RET;
</pre>
<p>Now let's get back to N Queens. Rather than immediately printing
the solutions, we will accumulate them in a list which is passed in
as a template argument of <tt class=
"literal">PlaceQueen&lt;&gt;</tt> and out as the typedef <tt class=
"literal">RET:</tt></p>
<pre class="programlisting">
// translation of dynamic placeQueen function. SolList is passed the list of existing
// solutions since we cannot print them immediately when found
template&lt;int N, int col=0, int row=0, class QueenList=Nil,
class SolList=Nil&gt;
class PlaceQueen {
  typedef Cons&lt;Queen&lt;row, col&gt;, QueenList&gt; NewQueenList;
//we add any solutions found by placing in the next column as the temporary TempSol
  typedef typename IF&lt;col &lt; N - 1,
                        PlaceQueen&lt;N, col+1, row, QueenList, SolList&gt;,
                        Identity&lt;SolList&gt; &gt;::RET::RET TempSol;
public:
  typedef typename IF&lt; HasConflicts&lt;Queen&lt;row, col&gt;, QueenList&gt;::RET,
                   Identity&lt;Identity&lt;TempSol&gt; &gt;,
                     IF&lt;row &lt; N - 1, PlaceQueen&lt;N, 0, row+1, NewQueenList, TempSol&gt;,
                      Identity&lt;Cons&lt;NewQueenList, TempSol&gt; &gt;
                 &gt;
  &gt;::RET::RET::RET RET;
};
</pre>
<p>This is enough to test our algorithm. We can find out the result
of the compiler's computation by asking for a nonexistent typedef,
e.g., <tt class="literal">foo</tt>, in the result. This will force
the compiler (gcc, at least), to output an error message containing
the type name:</p>
<pre class="programlisting">
const int NUMQUEENS=4;
int main() {
  PlaceQueen&lt;NUMQUEENS&gt;::RET::foo bar;
}
</pre>
<p>Compiling, we get:</p>
<pre class="programlisting">
jwalker@avakkai $ g++ NQueensStatic.cpp -ftemplate-depth-100 -w
NQueensStatic.cpp: In function 'int main()':
NQueensStatic.cpp:85: 'foo' is not a member of type
 Cons&lt;Cons&lt;Queen&lt;3,2&gt;,Cons&lt;Queen&lt;2,0&gt;,Cons&lt;Queen&lt;1,3&gt;,Cons&lt;Queen&lt;0,1&gt;,Nil&gt; &gt; &gt; &gt;,
Cons&lt;Cons&lt;Queen&lt;3,1&gt;,Cons&lt;Queen&lt;2,3&gt;,Cons&lt;Queen&lt;1,0&gt;,Cons&lt;Queen&lt;0,2&gt;,Nil&gt; &gt; &gt; &gt;,Nil&gt; &gt; '
NQueensStatic.cpp:85: parse error before ';'
</pre>
<p>The error message contains our solutions!</p>
<p>This is interesting, but not incredibly useful. What we would
like to have is a way to use the information from compile-time
computations at runtime. We can now use what Czarnecki and
Eisenecker call &quot;execute-loops&quot; to statically generate code. This
<tt class="literal">Foreach</tt> loop was inspired by the
<tt class="literal">EWHILE</tt>, <tt class="literal">EDO</tt>, and
<tt class="literal">EFOR</tt> examples in <span class=
"emphasis"><em>Generative Programming</em></span> [<a href=
"#Czarnecki-">Czarnecki-</a>].</p>
<pre class="programlisting">
//compare two types for equality
template&lt;class lhs, class rhs&gt; struct EqualType {enum {RET = false }; };
template&lt;class lhs&gt; struct EqualTypelhs, lhs {enum { RET = true };  };
struct EmptyStatement { static void exec() { } };
//loop over a cons-based list, executing Statement::exec() for each list member
template&lt;class Statement&gt;
struct Foreach {
  static void exec() {
    Statement::exec();
    IF&lt;EqualType&lt;typename Statement::NextList, Nil&gt;::RET,
      EmptyStatement,
      Foreach&lt;typename Statement::Next&gt;
    &gt;::RET::exec();
  }
};
</pre>
<p>We combine this code with a custom statement to loop over each
solution, and then over each queen within the solution in turn.</p>
<pre class="programlisting">
//statement for Foreach which prints a list of queens in 
// the same format as the dynamic solution
  template&lt;class QueenList&gt;
  struct PrintQueens   {
    typedef typename QueenList::Head Queen;
    static void exec() {
      std::cout &lt;&lt; &quot;(&quot; &lt;&lt; Queen::row &lt;&lt; &quot;,&quot; &lt;&lt; Queen::col &lt;&lt; &quot;);&quot;;
    }
    typedef typename QueenList::Tail NextList;
    typedef PrintQueens&lt;NextList&gt; Next;
  };
//statement for Foreach which prints a list of solutions one per line
  template&lt;class SolutionList&gt;
  struct PrintSolutions {
    typedef typename SolutionList::Head Solution;
    static void exec() {
      Foreach&lt;PrintQueens&lt;Solution&gt; &gt;::exec();
      std::cout &lt;&lt; std::endl;
    }
    typedef typename SolutionList::Tail NextList;
    typedef PrintSolutions&lt;NextList&gt; Next;
  };
  const int NUMQUEENS=4;
  int main() {
    typedef PlaceQueen&lt;NUMQUEENS&gt;::RET Solutions;
    Foreach&lt;PrintSolutions&lt;Solutions&gt; &gt;::exec();
  }
</pre>
<p>Let's try it:</p>
<pre class="programlisting">
jwalker@avakkai $ g++ NQueensStatic.cpp -ftemplate-depth-100 -w
jwalker@avakkai $ a.out
(3,2);(2,0);(1,3);(0,1);
(3,1);(2,3);(1,0);(0,2);
</pre>
<p>That's what we wanted. We have computed the solution at
compile-time and printed it at runtime. A similar technique could
be used to convert the compile-time solution into a run-time data
structure for further analysis.</p>
<p>Now for my dirty secret. As you may have guessed based on the
cautious <tt class="literal">NUMQUEENS=4</tt> statement above,
compile-time computation is not terribly efficient. Here is a
comparison of compile and execution times for the static and
dynamic solutions, varying the number of queens from 4 to 8 (tests
were run using gcc 2.95.3 on a Sun Enterprise 420R with quad 450Mhz
processors and 2GB of RAM).3</p>
<div class="informaltable">
<table border="1">
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody&gt;
<tr>
<td> </td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td colspan="6">Static Metaprogram</td>
</tr>
<tr>
<td>compile time</td>
<td>1.067s</td>
<td>4.655s</td>
<td>31.76s</td>
<td>696.8s</td>
<td>N/A</td>
</tr>
<tr>
<td>compiler peak VM usage</td>
<td>6.6MB</td>
<td>22.2MB</td>
<td>58.2MB</td>
<td>982MB</td>
<td>N/A</td>
</tr>
<tr>
<td>execution time</td>
<td>0.009s</td>
<td>0.008s</td>
<td>0.009s</td>
<td>0.010s</td>
<td>N/A</td>
</tr>
<tr>
<td colspan="6">Dynamic Program</td>
</tr>
<tr>
<td>compile time</td>
<td>1.019s</td>
<td>1.019s</td>
<td>1.019s</td>
<td>1.019s</td>
<td>1.019s</td>
</tr>
<tr>
<td>execution time</td>
<td>0.009s</td>
<td>0.012s</td>
<td>0.020s</td>
<td>0.059s</td>
<td>0.246s</td>
</tr>
&lt;/tbody&gt;
</table>
</div>
<p>In fact, I cannot even compile the 8-queens solution because the
machine runs out of virtual memory after exhausting all 2GB6! While
it is somewhat depressing that this canonical instance of N Queens
cannot be solved, I am quite satisfied by the wealth of knowledge I
learned constructing this example. As a similar exercise, it might
be fun to solve the Towers of Hanoi with static
metaprogramming.</p>
<p>Luckily, there are many useful techniques that can be performed
without taxing the compiler so heavily as this toy example.
Real-world uses of metaprogramming include customisation using
template traits (see Andrei Alexandrescu's Loki library [<a href=
"#Loki">Loki</a>] for excellent examples of traits) and
high-performance numeric computing with expression templates (for
which Blitz++ [<a href="#Blitz">Blitz</a>] is gaining fame).</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e479" id="d0e479"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Alexandrescu" id=
"Alexandrescu"></a>
<p class="bibliomixed">[Alexandrescu] Andrei Alexandrescu: Modern
C++ Design: Generic Programming and Design Patterns Applied,
Addison-Wesley, 2001, ISBN 0-201-70431-5</p>
</div>
<div class="bibliomixed"><a name="Czarnecki-" id="Czarnecki-"></a>
<p class="bibliomixed">[Czarnecki-] Krzysztof Czarnecki and Ulrich
W. Eisenecker: Generative Programming: Methods, Tools, and
Applications, Addison-Wesley, 2000, ISBN 0-201-30977-7</p>
</div>
<div class="bibliomixed"><a name="Boost" id="Boost"></a>
<p class="bibliomixed">[Boost] &quot;Boost C++ Libraries&quot;, <span class=
"bibliomisc"><a href="http://www.boost.org" target=
"_top">http://www.boost.org</a></span></p>
</div>
<div class="bibliomixed"><a name="Graham" id="Graham"></a>
<p class="bibliomixed">[Graham] Paul Graham: ANSI Common Lisp,
Prentice Hall, 1996, ISBN 0-13-370875-6</p>
</div>
<div class="bibliomixed"><a name="Williams" id="Williams"></a>
<p class="bibliomixed">[Williams] Anthony Williams: &quot;Introduction
to C++ Templates&quot;, Overload 45, October 2001</p>
</div>
<div class="bibliomixed"><a name="Loki" id="Loki"></a>
<p class="bibliomixed">[Loki] <span class="bibliomisc"><a href=
"http://www.awl.com/cseng/titles/0-201-70431-5/loki.zip" target=
"_top">http://www.awl.com/cseng/titles/0-201-70431-5/loki.zip</a></span></p>
</div>
<div class="bibliomixed"><a name="Blitz" id="Blitz"></a>
<p class="bibliomixed">[Blitz] &quot;Blitz++ Home Page&quot;, <span class=
"bibliomisc"><a href="http://www.oonumerics.org/blitz/" target=
"_top">http://www.oonumerics.org/blitz/</a></span></p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e26" href="#d0e26" id=
"ftn.d0e26">1</a>]</sup> Although in practice, the
implementation-dependent maximum depth for template instantiations
means that this Turing machine may have a very short tape. The C++
Standard only requires a maximum depth of 17; anything else is an
extension. I used gcc 2.95.3 to compile the examples in this
article. Gcc has a -ftemplate-depth-xxx switch allowing the user to
explicitly set the maximum depth for template instantiations.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e64" href="#d0e64" id=
"ftn.d0e64">2</a>]</sup> Strictly speaking, the C++ standard
requires that a definition be provided for a static constant member
if it is used in the program. However, the intent (and probable
result using existing compilers) seems to be that the definition
should only be required if the static constant is used in a way
requiring storage in memory, e.g., taking the address.
Additionally, curiously enough, the enum version compiles over
twice as fast as the static const int version on gcc 2.95.3.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e109" href="#d0e109" id=
"ftn.d0e109">3</a>]</sup> Metaobjects is probably a misuse of the
meta prefix. More accurately, these are metaprogramming
objects.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e129" href="#d0e129" id=
"ftn.d0e129">4</a>]</sup> &quot;The names car and cdr derive from the
internal representation of lists in the first Lisp implementation:
car stood for 'contents of the address part of the register' and
cdr stood for 'contents of the decrement part of the register'&quot;
[<a href="#Graham">Graham</a>].</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e199" href="#d0e199" id=
"ftn.d0e199">5</a>]</sup> The &quot;typename&quot; keyword must be used to
qualify Dependent Names. Anthony Williams has written an
informative article on C++ templates which unfortunately arrived in
my mailbox too late to help me with these details [<a href=
"#Williams">Williams</a>].</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
