Home > Articles > Programming > C/C++

  • Print
  • + Share This
  • 💬 Discuss
This chapter is from the book

This chapter is from the book

17.8 Afternotes

As mentioned earlier, the earliest documented example of a metaprogram was by Erwin Unruh, then representing Siemens on the C++ standardization committee. He noted the computational completeness of the template instantiation process and demonstrated his point by developing the first metaprogram. He used the Metaware compiler and coaxed it into issuing error messages that would contain successive prime numbers. Here is the code that was circulated at a C++ committee meeting in 1994 (modified so that it now compiles on standard conforming compilers)3:

// meta/unruh.cpp

// prime number computation by Erwin Unruh

template <int p, int i>
class is_prime {
  public:
    enum { prim = (p==2) || (p%i) && is_prime<(i>2?p:0),i-1>::prim
         }; 
}; 

template<>
class is_prime<0,0> {
  public:
    enum {prim=1};
}; 

template<>
class is_prime<0,1> {
  public:
    enum {prim=1};
}; 

template <int i>
class D {
  public:
    D(void*);
}; 

template <int i>
class Prime_print {      // primary template for loop to print prime numbers
  public:
    Prime_print<i-1> a; 
    enum { prim = is_prime<i,i-1>::prim
         }; 
    void f() {
        D<i> d = prim ? 1 : 0;
        a.f();
    } 
}; 

template<>
class Prime_print<1> {   // full specialization to end the loop
  public:
    enum {prim=0}; 
    void f() {
        D<1> d = prim ? 1 : 0;
    }; 
}; 

#ifndef LAST 
#define LAST 18 
#endif 

int main()
{
    Prime_print<LAST> a; 
    a.f(); 
} 

If you compile this program, the compiler will print error messages when in Prime_print::f(), the initialization of d fails. This happens when the initial value is 1. because there is only a constructor for void*, and only 0 has a valid conversion to void*. For example, on one compiler we get (among other messages) the following errors:

unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<17>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<13>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<11>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<7>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<5>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<3>&39; requested
unruh.cpp:36: conversion from &39;int&39; to non-scalar type &39;D<2>&39; requested

The concept of C++ template metaprogramming as a serious programming tool was first made popular (and somewhat formalized) by Todd Veldhuizen in his paper Using C++ Template Metaprograms (see [VeldhuizenMeta95]). Todd’s work on Blitz++ (a numeric array library for C++, see [Blitz++]) also introduced many refinements and extensions to the metaprogramming (and to expression template techniques, introduced in the next chapter).

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus