Blog Archives

Meta-programming in C++, a functional language for your compiler!

My last post was 2 years ago… apparently I don’t have any discipline to keep a blog =P. But I’ll try again this time.

The following is just a very interesting piece of code showing the meta-programming capabilities of C++. Unfortunately this is a quite unknown and considered super advanced feature. However, it’s not that complicated and, if used appropriately, can originate very elegant (and useful) code. By the other hand, you can do many REALLY sick things with it. Sure, there’s nothing new here. After all, as Stroustrup himself once pointed out: “In C++ it’s harder (to shoot yourself in the foot), but when you do, you blow off your whole leg”.

template<int N> struct F {
    enum { value = N * F<N-1>::value };
}

template<> struct F<0> {
    enum { value = 1 };
}

int x = F<5>::value;

So… can you tell the value of x at COMPILE TIME? Made it right who said 120. But… why? If you understand meta-programming there’s nothing surprising here. However, for those who don’t, it can be crypt. Think about the templated struct as a function evaluated at compile time and you immediately understand it. The struct F is just a recursive implementation of a factorial.

Because templated declarations are resolved at compile time, you can implement VERY, VERY sophisticated pre-processing logic in your code. As templates can be specialized and recursively declared, you have an almost full functional programming language embedded in your C++ compiler. In fact, the C++ meta-programming capability is Turing complete as Steve Meyer points out in his book Effective C++. Can you appreciate how amazing this is? There are libraries using this to extend C++ itself, providing additional features to the language. One example is Boost.

Although meta-programming is fantastic, we all know: there’s no free-lunch. It’s not hard to see that meta-programming has a HUGE potential to slow down the build. You can even write code that falls into infinite loop DURING compilation (try “int x = F<-1>::value;”; in fact, it’ll lead to a stack overflow, not an infinite loop… but you got the idea =P). Not to mention the possible negative impact in readability.

Ok… this is it… I believe this was nicer than the previous posts (most people seem to think floating-point is boring) =P. During these 2 years a lot of things changed. The most important: I changed my research area. I’m not working with floating-point stuff anymore. Despite I like it, I’ve discovered a much more interesting topic to study: machine learning (and, collaterally, computer vision). So, hereafter likely you’ll see posts related to it… if my laziness in writing contribute, of course =D.