2

I'm struggling with templates ! Consider the following code:

template <typename... Ts> struct Sequence {};

template<unsigned N> struct B {
  template<unsigned P> struct C {
    typedef int type;
  };
};

Then this is perfectly correct:

template<unsigned... Is>
struct Loop2 {
  typedef Sequence< typename B<5>::C<Is>::type... > type;
};

Loop2<3,1> l;

Therefore I can't understand why this templated version:

template<unsigned N, unsigned... Is>
struct Loop3 {
  typedef Sequence< typename B<N>::C<Is>::type... > type;
};

isn't accepted by the compiler. It raise the following error:

essai.cpp:29:51: error: template argument 1 is invalid
   typedef Sequence< typename B<N>::C<Is>::type... > type;

For the information I got this with

g++ (SUSE Linux) 4.8.1 20130909 [gcc-4_8-branch revision 202388]

Thanks for any help !

By the way: any suggestion for a better title is welcome !

dyp
  • 38,334
  • 13
  • 112
  • 177
hivert
  • 10,579
  • 3
  • 31
  • 56
  • *"Therefore I can't understand why this templated version [..] isn't accepted by the compiler"* Because there could be a `template<> struct B<4> { int C; };`, i.e., that `C` is a template isn't obvious to the compiler w/o a specific specialization of `B`. – dyp Feb 01 '14 at 22:20

1 Answers1

4

As B is not a specific type anymore, you need to flag C with the template keyword as it is depenend on the value of N. Using the follwing code should work:

template<unsigned N, unsigned... Is>
struct Loop3 {
  typedef Sequence< typename B<N>::template C<Is>::type... > type;
};
Uwe L. Korn
  • 8,080
  • 1
  • 30
  • 42
  • You seems to be right but I don't understand what you mean by "B is not a specific type anymore". Can you clarify or point to a reference ? – hivert Feb 01 '14 at 22:19
  • With B<5> in Loop2 we have instantiated a type from a template, i.e. the compiler is given a specific type whereas in the B situation we still have a template that depends on how N will be choosen "some time later" and may vary between usages of Loop3. – Uwe L. Korn Feb 01 '14 at 22:22
  • @hivert: Stated in a different way: since `B` is *dependent* on the template arguments, you need to qualify any nested class/template with the `typename`/`template` keywords – David Rodríguez - dribeas Feb 01 '14 at 22:28
  • Thanks a lot to both of you for those explanations ! – hivert Feb 02 '14 at 08:12