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?
Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.
A variadic template is a class or function template that supports an arbitrary number of arguments. This mechanism is especially useful to C++ library developers: You can apply it to both class templates and function templates, and thereby provide a wide range of type-safe and non-trivial functionality and flexibility.
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.
Your code is ill-formed, there is equivalent example in the standard (under 14.3.3/2):
...
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
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With