Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ and CRTP pattern implementation and compiler dilemma

I'm trying to compile the following bit of code, however there seems to be an issue that I can't seem to resolve:

template <int x>
struct count_x
{
   enum { x_size = x };
};

template <typename y>
struct crtp_base
{
   typedef typename y::count_t count_t;
   crtp_base(const count_t&){}
};

template <int x>
struct derived : public crtp_base<derived<x> >
{
   typedef typename count_x<x> count_t;
   typedef crtp_base<derived<x> > base_t;
   derived(const count_t& c) : base_t(c){}
};


int main()
{
   derived<2> d((count_x<2>()));
   return 0;
}

When compiled wth clang 3.1, the following is the error:

c:\clangllvm\code\example.cc:18:21: error: expected a qualified name after 'typename'
   typedef typename count_x<x> count_t;
                    ^
c:\clangllvm\code\example.cc:18:21: error: typedef name must be an identifier
   typedef typename count_x<x> count_t;
                    ^~~~~~~~~~
c:\clangllvm\code\example.cc:18:28: error: expected ';' at end of declaration list
   typedef typename count_x<x> count_t;
                           ^
                           ;
c:\clangllvm\code\example.cc:20:18: error: no template named 'count_t'; did you mean 'count_x'?
   derived(const count_t& c)
                 ^~~~~~~
                 count_x
c:\clangllvm\code\example.cc:2:8: note: 'count_x' declared here
struct count_x
       ^
c:\clangllvm\code\example.cc:20:18: error: use of class template count_x requires template arguments
   derived(const count_t& c)
                 ^
c:\clangllvm\code\example.cc:2:8: note: template is declared here
struct count_x
       ^
5 errors generated.

I believe it has got something to do with the way the templates are determined at compile time and if they are determined as being a type at the right time. I've also tried adding "using base_t::count_t; " to no avail. Other than that, the diagnostic produced by the compiler has left me really lost. An answer or a suggestion on something to read about this error would be appreciated.

like image 210
Switzy Avatar asked Oct 12 '12 03:10

Switzy


1 Answers

count_x<x> is not a qualified name (it has no :: at all!), so it cannot be preceeded with typename.

Once you fix this, the code will still fail because the derived type's nested typedefs were not seen by the compiler yet when it instantiates the CRTP base. This other question shows some alternatives.

like image 162
R. Martinho Fernandes Avatar answered Oct 16 '22 00:10

R. Martinho Fernandes