I have a template class that accepts from 1 to 8 integer arguments. The permitted range for each argument is 0..15. A default value of 16 for each argument allows me to detect unused arguments.
I would like to have the number of user-supplied arguments available as a compile-time constant. I can do this using a template helper class and a lot of partial specialisation.
My question is, can I clean this up using a bit of recursive metaprogramming. What I have works but it feels like it could be improved syntactically.
Variadic templates and anything else c++0x are not available to me, sadly.
#include <stdint.h>
#include <iostream>
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5,uint8_t p6,uint8_t p7>
struct Counter { enum { COUNT=8 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5,uint8_t p6>
struct Counter<p0,p1,p2,p3,p4,p5,p6,16> { enum { COUNT=7 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5>
struct Counter<p0,p1,p2,p3,p4,p5,16,16> { enum { COUNT=6 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4>
struct Counter<p0,p1,p2,p3,p4,16,16,16> { enum { COUNT=5 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3>
struct Counter<p0,p1,p2,p3,16,16,16,16> { enum { COUNT=4 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2>
struct Counter<p0,p1,p2,16,16,16,16,16> { enum { COUNT=3 }; };
template<uint8_t p0,uint8_t p1>
struct Counter<p0,p1,16,16,16,16,16,16> { enum { COUNT=2 }; };
template<uint8_t p0>
struct Counter<p0,16,16,16,16,16,16,16> { enum { COUNT=1 }; };
template<uint8_t p0,uint8_t p1=16,uint8_t p2=16,uint8_t p3=16,
uint8_t p4=16,uint8_t p5=16,uint8_t p6=16,uint8_t p7=16>
struct MyClass {
void printArgCount() {
std::cout << Counter<p0,p1,p2,p3,p4,p5,p6,p7>::COUNT << std::endl;
}
};
main() {
MyClass<4,7,8,12,15,1> foo;
foo.printArgCount();
}
Why not just checking the first
16that appears ?