xmh0511
xmh0511

Reputation: 7369

Some confusions about pack expansion in template parameter section

temp.param#15

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.

  1. 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?

  2. 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

  1. According to the whole paragraph, I still can't understand why 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

Answers (1)

Caleth
Caleth

Reputation: 63162

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.

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 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?

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

Related Questions