I use the compile time counter in some applications, and it is really useful. Yesterday I wanted to compile a program with gcc (I used to use msvc before), and the behavior of the counter changed in template classes (it no longer works in template classes).
Too simplified code:
// Maximum value the counter can hold #define MAX_COUNT 64 // Used to store a number as the size of the structure template<unsigned int n> struct Count { bool data[n]; }; // Used to overload functions while automatically selecting the // right one based on the counter value (see following code) template<int n> struct cn : public cn<n-1> {}; template<> struct cn<0> {}; struct Test { #define COUNT \ ((sizeof(f(cn<MAX_COUNT + 1>())) / sizeof(bool)) - 1) static Count<1> f(cn<1>); /* f(cn<65>()) will 'call' f(cn<1>) and return a Count<1> with size 1 -> count = 0; */ static const int a = COUNT; static Count<COUNT + 2> f(cn<COUNT + 2>); // increase counter /* now Count<2> f(cn<2>) is defined, so: f(cn<65>()) will 'call' f(cn<2>) and return a Count<2> with size 2 -> count = 1; */ static const int b = COUNT; };
The idea is to use function overloading, and if you check the code above, it will work fine ( a == 0 and b == 1 ).
However, if the struct Test is made by a template (just adding template<something> before its declaration, for example, you do not need to use the template parameter), the counter breaks , and I end a == b == 1 . It also means that under these conditions it is not possible to increase the counter.
So here are my questions:
- What template rules work here?
- why is this particular behavior?
- Do you have an idea on how to work on the counter to actually work?
Note. I need a C ++ 03 answer for compatibility with older compilers (even if I'm interested in finding out if the rules for this particular case have changed for C ++ 11)
EDIT : some outputs:
EDIT 2
GCC seems to accept Count as a dependent name, as it is observed here (thanks dyp). I sent an error message to gcc bugzilla here .
source share