Template vs non-template class, different behavior for compilers

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:

  • VC2010:

     Templated a = 0 b = 1 
  • GCC 4.8.1 :

     Templated a = 1 b = 1 
  • Clang 3.4 (thanks to dyp):

     Templated a = 0 b = 1 

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 .

+2
source share
1 answer

These can be attributes for searching for two-phase names in C ++. This is a feature of C ++ 03 that also exists in C ++ 11. The LLVM project made an article about this function and compared its Clang compiler with GCC and Visual C ++. GCC and Visual C ++ do not support this feature, but Visual C ++ has a name processing method that will allow two-phase search-dependent code to run more often than GCC. It also allows code that is not valid C ++ code to also work in accordance with the article.

EDIT : I am reading the article incorrectly, GCC implements a two-phase search, but it can choose the delay of the search before creating the template. This seems to be a bug in GCC.

0
source

All Articles