Saturday, October 22, 2011

Template metaprogramming

Template metaprogramming is a fairly useless feature of C++, but we can have some fun with it. I've been trying to improve my functional programming skill set, so a friend proposed a problem:

Write a routine that can count bits in an integer at compile time using templates.

Here's the basic recursive solution:

int count_bits(unsigned int x)
{
if(x == 0)
{
return 0;
}
else
{
return (x & 0x1) + count_bits(x >> 1);
}
}



This isn't what I had in mind though. I want to do this using templates. That gets us there:

#include <stdio.h>

template<unsigned long long input>struct numBits
{
static const unsigned long long value = numBits<(input >> 1)>::value+(input&1);
};

template <> struct numBits<0>
{
static const unsigned long long value=0;
};

#define output(num) printf("0x%llX: %u\n", (unsigned long long)num, numBits<(unsigned long long)num>::value)

int main(int argc, const char **argv)
{
output(0x0);
output(0x1);
output(0x2);
output(0x3);
output(0x4);
output(0x11);
output(0x111);
output(0x1000);
output(0x1010);
output(0x1001001);
output(0xFFFFFFFFFFFFFFFEULL);
output(0xFFFFFFFFFFFFFFFFULL);

return 0;
}




Ha! The biggest problem with this is it only works on constants (it IS compile time). It's an academic exercise, as there's not much good reason to use this over the other options. The output looks like:

0x0: 0
0x1: 1
0x2: 1
0x3: 2
0x4: 1
0x11: 2
0x111: 3
0x1000: 1
0x1010: 2
0x1001001: 3
0xFFFFFFFFFFFFFFFE: 63
0xFFFFFFFFFFFFFFFF: 64

No comments:

Post a Comment