template <int Depth, int A, typename B> struct Binary { enum { value = 1 + Binary<depth-1, 0, Binary>::value + Binary<depth-1, 1, Binary>::value }; }; template<int a, typename B> struct Binary<0, A, B> { enum { value = 1 }; }; int main(void) { static const int N = 10; const int instantiations = Binary<N,0,int>::value; }

template <class V1, class V2> struct Intersection { typedef typename boost::mpl::copy_if<V1, boost::mpl::contains<V2, boost::mpl::placeholders::_1> >::type type; };

struct null_type {}; template <typename... Arg> struct vector {}; template <typename V> struct front; template <typename V> struct pop_front; template <typename Head, typename... Tail> struct front <vector <Head, Tail...> > { typedef Head type; }; template <> struct front <vector <> > { typedef null_type type; }; template <typename Head, typename... Tail> struct pop_front <vector <Head, Tail...> > { typedef vector<Tail...> type; }; template <> struct pop_front <vector <> > { typedef vector<> type; }; template <typename Vector, typename T> struct push_back; template <typename T, typename... Args> struct push_back < vector<Args...>, T> { typedef vector<Args..., T> type; }; template <typename Vector> struct size; template <typename... Args> struct size <vector <Args...> > { typedef size type; enum { value = sizeof...(Args) }; }; template <typename Vector, typename What> struct contains; template <typename What, typename Head, typename... Tail> struct contains < vector<Head, Tail...>, What> : std::conditional < std::is_same<Head, What>::value, std::true_type, contains < vector<Tail...>, What> >::type { typedef contains type; }; template <typename What> struct contains <vector<>, What> { typedef contains type; enum { value = 0 }; }; template <class V1, class V2> struct Intersection; template <class V1, class V2, unsigned int N> struct Intersection_impl { typedef typename front<V2>::type Head; typedef typename pop_front<V2>::type Tail; typedef typename Intersection<V1, Tail>::type I; typedef typename std::conditional<contains<V1, Head>::value, typename push_back<I, Head>::type, I >::type type; }; template <class V1, class V2> struct Intersection_impl <V1, V2, 0> { typedef vector<> type; }; template <class V1, class V2> struct Intersection { typedef typename Intersection_impl<V1, V2, size<V1>::value * size<V2>::value>::type type; };

One of the practical issues with C++ meta-programming is its speed. C++ programs that use heavy meta-programming can be notoriously slow to compile on contemporary compilers. Things are changing, however. Check the following comparison of gcc 4.5 against gcc 4.4.3. The first graph is obtained from a program that creates a binary tree of template instantiations. The x-axis shows the number of instantiations when value of N goes from 8 to 17. I could not build up patience for gcc 4.4.3 beyond 16363 instantiations (N=13). On the other hand, gcc 4.5 does pretty good and its increase in compilation time is indeed linear as mentioned here . Here is the program that creates a binary tree of template instantiations.The second graph is obtained from a program that finds an intersection of two MPL vectors. Again gcc 4.5 shows linear increase in compilation time as opposed to gcc 4.4.3. Here is the intersection program.While all that is already exciting, it fades in comparison to the performance of variadic templates in C++0x. The green line in the second graph shows negligible effect on performance with the increasing number of template parameters. Here is my intersection metaprogram using variadic templates.So long story short, seems like better days are ahead for C++ meta-programming!