Search code examples
c++templatesmetaprogrammingcircular-dependency

Size of parameter pack in template specialization


I have a template that provides a type for any given Order in the range from 0 to MaxOrder.

template <class Graph, int Order> TypeHelper;

This is necessary because TypeHelper<Graph, k> depends on TypeHelper<Graph, 0>, TypeHelper<Graph, k - 1> and TypeHelper<Graph, k + 1>.

Graph is a variadic template that serves as a container for the type of the Payload for any given order.

template <class... Payloads> Graph;

In order to terminate the recursion at TypeHelper<Graph, 0> and TypeHelper<Graph, MaxOrder> these are specialized. The former is straight forward but I cannot figure out how to derive MaxOrder from the number of types in Payloads....
One obvious solution is to introduce MaxOrder as a template parameter of Graph.
As an example:

template <int MaxOrder, class... Payloads> Graph;

template <template <int, class...> class Graph, int MaxOrder, class... Payloads>
struct TypeHelper<Graph<MaxOrder, Payloads...>, MaxOrder>

But I would prefer something like this

template <template <class...> class Graph, class... Payloads>
struct TypeHelper<Graph<Payloads...>, sizeof...(Payloads)>

But this does not work.

Further reading: Is sizeof... allowed in template arguments for specialization?

Any suggestions?


Solution

  • I'm not sure I got the problem, but you can still use an intermediate class that inherits from your actual implementation:

    template <class Graph, int Order>
    struct TypeHelperImpl;
    
    // specializations of TypeHelperImpl
    
    template <typename...>
    struct TypeHelper;
    
    template <template <class...> class Graph, class... Payloads>
    struct TypeHelper<Graph<Payloads...>, Payloads...>
        : TypeHelperImpl<Graph<Payloads...>, sizeof...(Payloads)> {};