Can a variadic template match a non-variadic template parameter?

c++, c++11, template-meta-programming, templates, variadic

Solution

Someone correct me if I'm wrong but it seems like it's correct from this quote:

3 A template-argument matches a template template-parameter (call it P) when each of the template parameters in the template-parameter-list of the template-argument’s corresponding class template or [FI 11] template aliasalias template (call it A) matches the corresponding template parameter in the template-parameter-list of P

`A` (the given template) has to match each of it's templates parameters to `P`'s the template template.

From the second part of the section we learn the restriction doesn't apply in the reverse, meaning a template template containing a parameter pack can match anything.

When P’s template-parameter-list contains a template parameter pack (14.5.3), the template parameter pack will match zero or more template parameters or template parameter packs in the template-parameter- list of A with the same type and form as the template parameter pack in P

As you probably already knew the way to make it work is

template<template<class> class T,class U>                                       
struct apply                                                                       
{                                                                                  
         typedef T<U> type;                                                        
};                                                                                 

template<class T> using tuple_type  = std::tuple<T>;
typedef apply<tuple_type,int>::type tuple_of_one_int;                          

The c++11 standard also has an equivalent example to yours.

template <class ... Types> class C { /∗ ... ∗/ };

template<template<class> class P> class X { /∗ ... ∗/ };

X<C> xc; //ill-formed: a template parameter pack does not match a template parameter  

The last comment completely describes your situation, class `C` would be the equivalent of `std::tuple` in this case.

Problem

Consider the following snippet: ``` template<template<class> class T,class U> struct apply { typedef T<U> type; }; typedef apply<std::tuple,int>::type tuple_of_one_int; //Should be std::tuple<int> ``` GCC 4.8.2. says: ``` type/value mismatch at argument 1 in template parameter list for [...] struct apply expected a template of type ‘template<class> class T’, got ‘template<class ...> class std::tuple’ ``` Which basically means that a variadic template like `std::tuple` is not a valid template argument for `T` in `apply`. Is this a GCC bug or does the standard mandates this behaviour?

Original source