Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I partially specialize a template with a pattern like foo<T..., int, U...>?

If this is possible, one can index into a variadic template parameter pack without recursion. However, GCC is refusing to pick up my partial specialization here:

template <int I, typename List>
struct element_impl;

template <typename... TL, int... IL, typename T, int I, typename... TR, int... IR>
struct element_impl<I, typelist<pair<TL,IL>..., pair<T,I>, pair<TR,IR>...>> {
    typedef T type;
};

prog.cpp: In instantiation of 'element<0, typelist<int, double, char, float, long int> >':
prog.cpp:52:34: instantiated from here
prog.cpp:47:79: error: invalid use of incomplete type 'struct element_impl<0, typelist<pair<int, 0>, pair<double, 1>, pair<char, 2>, pair<float, 3>, pair<long int, 4> >'

Is GCC buggy, or am I ignoring some limitation of variadic templates?

like image 541
R. Martinho Fernandes Avatar asked Jun 17 '12 17:06

R. Martinho Fernandes


2 Answers

The spec says at 14.8.2.5p9

If P has a form that contains <T> or <i>, then each argument Pi of the respective template argument list P is compared with the corresponding argument Ai of the corresponding template argument list of A. If the template argument list of P contains a pack expansion that is not the last template argument, the entire template argument list is a non-deduced context.

Your typelist<T> unfortunately matches that pattern.

like image 171
Johannes Schaub - litb Avatar answered Nov 07 '22 18:11

Johannes Schaub - litb


AFAICT, the rules for matching partial specializations are the same as the rules type deduction of function parameters. And §14.8.2.1/1 says the following:

For a function parameter pack that occurs at the end of the parameter-declaration-list, the type A of each remaining argument of the call is compared with the type P of the declarator-id of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. For a function parameter pack that does not occur at the end of the parameter-declaration-list, the type of the parameter pack is a non-deduced context.

So the packs TL and IL cannot be deduced in this case, and the partial specialization is not picked.

like image 30
R. Martinho Fernandes Avatar answered Nov 07 '22 18:11

R. Martinho Fernandes