Reputation: 7369
If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a parameter pack ([dcl.fct]), then the template-parameter is a template parameter pack. A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion. Similarly, a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded parameter packs is a pack expansion. A template parameter pack that is a pack expansion shall not expand a parameter pack declared in the same template-parameter-list. [ Example:
template <class... Types> class Tuple; // Types is a template type parameter pack
// but not a pack expansion
template <class T, int... Dims> struct multi_array; // Dims is a non-type template parameter pack
// but not a pack expansion
template<class... T> struct value_holder {
template<T... Values> struct apply { }; // Values is a non-type template parameter pack
// and a pack expansion
};
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
// pack T within the same template parameter list
— end example ]
About the whole paragraph, I have much confusions about it. I will list my confusions in the following.
a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion.
About this sentence, How can a parameter-declaration contain more than one type? A parameter-declaration
either be the form like T variable
or T... variable
, the first is a simple parameter-declaration, the second is a parameter pack that can accept more than one arguments of the same type T, whatever, they are only permitted to accept arguments of the same type specified by T
. Does it say type-parameter? it seems to only type-parameter pack can accept more than one difference types. Or anything others? How to read this sentence?
a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded parameter packs is a pack expansion.
Does this sentence refer to a template template-parameter? It seems to only this kind template-parameter can have template-parameter-list, Due to:
template < template-parameter-list > type-parameter-key ...opt identifier opt
Dims
is not a pack expansion but Values
is, What can be a pack expansion according to this paragraph? It seems to nothing implies it would be as the form like Something ...
or Did I miss that in this sentence?If I have any misunderstanding. Please correct me.
Upvotes: 1
Views: 294
Reputation: 63162
How can a parameter-declaration contain more than one type? A parameter-declaration either be the form like
T variable
orT... variable
, the first is a simple parameter-declaration, the second is a parameter pack that can accept more than one arguments of the same typeT
, whatever, they are only permitted to accept arguments of the same type specified byT
.
You are missing the case where T
is a parameter pack. The example lists this
template<class... T> struct value_holder {
template<T... Values> struct apply { }; // Values is a non-type template parameter pack
// and a pack expansion
};
Here Values
have different types. We are expanding T
to define Values
, so this is a pack expansion. Values
is the parameter pack, and it's type is T
According to the whole paragraph, I still can't understand why
Dims
is not a pack expansion butValues
is, What can be a pack expansion according to this paragraph? It seems to nothing implies it would be as the form likeSomething ...
or Did I miss that in this sentence?
You need to have a template within a variadic template definition. That's why value_holder
has an inner struct apply
, this paragraph is saying you can't do it in one template, you need to nest them. From the example
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
// pack T within the same template parameter list
Upvotes: 3