C++ passing template parameter pack from one variadic template to another causes compiler error

mrausch

The following code causes compiler errors, but only for gcc (up to 5.2) and clang (up to 3.7). VS2015 compiles without promblems. (For g++ you have to use the option -std=c++14)

//************************************************
template <int... items>
struct Sequence {
//************************************************
public:
  enum { size = sizeof...(items) };
  operator int() const { return data[rank - 1]; }
  Sequence& operator=(const Sequence& s) { rank = s.rank; return *this; }
  int get_rank() const { return rank; }
  bool first() { rank = 1; return true; }
  bool last() { rank = size; return true; }
  bool next() { return (rank < size) ? ++rank, true : false; }
  bool prev() { return (rank > 1) ? --rank, true : false; }
  bool is_first() { return rank == 1; }
  bool is_last() { return rank == size; }
protected:
  static const int data[sizeof... (items)];
  int rank = 1;
};

template <int... items> 
const int Sequence<items...>::data[sizeof...(items)] = { items... };


//************************************************
template <unsigned N, template <unsigned> class F, int... items> 
struct generate_sequence {
//************************************************
  typedef typename generate_sequence<N - 1, F, F<N>::value, items...>::result result;
};

//************************************************
template <template <unsigned> class F, int... items> 
struct generate_sequence<0, F, items...> {
//************************************************
  typedef Sequence<F<0>::value, items...> result;
};


//************************************************
template <int... coeffs>
struct polynomial {
//************************************************
  template <int var, int a0, int... ai> struct ipoly { enum { value = a0 + var * ipoly<var, ai...>::value }; };
  template <int var, int a0> struct ipoly<var, a0> { enum { value = a0 + 0 * var }; };

  template <unsigned index>
  class number_generator { public: enum { value = ipoly<index + 1, coeffs...>::value }; };
};


//************************************************
template <unsigned N>
class NaturalNumbers : public generate_sequence<N - 1, polynomial<0,1>::number_generator>::result {};
//************************************************

//************************************************
template <unsigned N, int... coeffs>
class PolynomialNumbers : public generate_sequence<N - 1, polynomial<coeffs...>::number_generator>::result {};
//************************************************

int main() {
  NaturalNumbers<10> nn;
  PolynomialNumbers<10,0,1> pn;
}

The compiler output is as follows:

bug.cpp:59:98: error: type/value mismatch at argument 2 in template parameter list for 'template<unsigned int N, template<unsigned int <anonymous> > class F, int ...items> struct generate_sequence'
 class PolynomialNumbers : public generate_sequence<N - 1, polynomial<coeffs...>::number_generator>::result {};
                                                                                                  ^
bug.cpp:59:98: note:   expected a class template, got 'polynomial<coeffs ...>::number_generator'
bug.cpp:59:101: error: expected '{' before 'result'
 class PolynomialNumbers : public generate_sequence<N - 1, polynomial<coeffs...>::number_generator>::result {};
                                                                                                     ^
bug.cpp: In function 'int main()':
bug.cpp:64:27: error: non-template type 'PolynomialNumbers' used as a template
   PolynomialNumbers<10,0,1> pn;
                           ^

Is this a compiler bug or is the code somehow wrong? For me the key lies in the line

expected a class template, got 'polynomial::number_generator'

of the compiler output. The compiler obviously does not realize that 'polynomial::number_generator' in fact is a template. What do you mean?

Barry

Since number_generator is a dependent name, you have to prefix it with the template keyword:

template <unsigned N, int... coeffs>
class PolynomialNumbers 
: public generate_sequence<
      N - 1, 
      polynomial<coeffs...>::template number_generator
                          // ^^^^^^^^
      >::result 
{};

As a side-note, it might be better to avoid passing template templates anywhere and try to rewrite your number_generator to be more like a metafunction class:

class number_generator {
public: 
    template <unsigned index>
    using apply = ipoly<index + 1, coeffs...>;
};

That'll make all your code easier since types are first-class citizens and anything that isn't a type (i.e. a template template or a value) is much more difficult to deal with.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Passing a Parameter From One Template to Another

From Dev

a variadic template as a template parameter without pack expansion

From Dev

How to extract a value from a variadic template parameter pack by index?

From Dev

template of variadic template: parameter pack expects a type template

From Dev

Multiple Variadic Parameter Pack for Template Class

From Dev

Check if a type is passed in variadic template parameter pack

From Dev

Go template Passing data from one to another

From Dev

Variadic template pack expansion

From Dev

Passing variadic function template arguments to another function

From Dev

Passing variadic template function arguments to another function

From Dev

Making a variadic templete from another variadic template

From Dev

C++11: What's the difference between "parameter pack" and "variadic template"?

From Dev

C++ - deduce parameter pack (variadic template) constructor and copy constructor by enable_if_t

From Dev

Why is this substitution of variadic template parameter failing ? (pack before fixed arguments)

From Dev

Insert/remove type into variadic template list (parameter pack)

From Dev

Compile time array from C++ template parameter pack

From Dev

c++ Unpacking parameter pack from template arguments

From Dev

variadic template pack within decltype

From Dev

Variadic template indexed pack expansion

From Dev

variadic template template parameter syntax

From Dev

Error with variadiac template: "parameter pack must be expanded"

From Dev

Error when trying to expand template parameter pack

From Dev

Output operator for class template with variadic template pack

From Dev

Clang variadic template specialization error: non-deducible template parameter

From Dev

Deduce template parameter pack from function call

From Dev

Template Meta-programming, with Variadic Templates: compiler error

From Dev

Template Meta-programming, with Variadic Templates: compiler error

From Dev

variadic variadic template template specialisation error

From Dev

Can one parameter in a C++11 template depend on another?

Related Related

  1. 1

    Passing a Parameter From One Template to Another

  2. 2

    a variadic template as a template parameter without pack expansion

  3. 3

    How to extract a value from a variadic template parameter pack by index?

  4. 4

    template of variadic template: parameter pack expects a type template

  5. 5

    Multiple Variadic Parameter Pack for Template Class

  6. 6

    Check if a type is passed in variadic template parameter pack

  7. 7

    Go template Passing data from one to another

  8. 8

    Variadic template pack expansion

  9. 9

    Passing variadic function template arguments to another function

  10. 10

    Passing variadic template function arguments to another function

  11. 11

    Making a variadic templete from another variadic template

  12. 12

    C++11: What's the difference between "parameter pack" and "variadic template"?

  13. 13

    C++ - deduce parameter pack (variadic template) constructor and copy constructor by enable_if_t

  14. 14

    Why is this substitution of variadic template parameter failing ? (pack before fixed arguments)

  15. 15

    Insert/remove type into variadic template list (parameter pack)

  16. 16

    Compile time array from C++ template parameter pack

  17. 17

    c++ Unpacking parameter pack from template arguments

  18. 18

    variadic template pack within decltype

  19. 19

    Variadic template indexed pack expansion

  20. 20

    variadic template template parameter syntax

  21. 21

    Error with variadiac template: "parameter pack must be expanded"

  22. 22

    Error when trying to expand template parameter pack

  23. 23

    Output operator for class template with variadic template pack

  24. 24

    Clang variadic template specialization error: non-deducible template parameter

  25. 25

    Deduce template parameter pack from function call

  26. 26

    Template Meta-programming, with Variadic Templates: compiler error

  27. 27

    Template Meta-programming, with Variadic Templates: compiler error

  28. 28

    variadic variadic template template specialisation error

  29. 29

    Can one parameter in a C++11 template depend on another?

HotTag

Archive