The wording about instantiation of a pack expansion in [temp.variadic]

Viewed 86

I wonder Is it a mis-wording in the following quote, that is

temp.variadic#7

The instantiation of a pack expansion that is neither a sizeof... expression nor a fold-expression produces a list E1,E2,...En , where N is the number of elements in the pack expansion parameters. Each Ei is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element. Such an element, in the context of the instantiation, is interpreted as follows:

  • if the pack is a template parameter pack, the element is a template parameter of the corresponding kind (type or non-type) designating the type or value from the template argument; otherwise,
  • if the pack is a function parameter pack, the element is an id-expression designating the function parameter that resulted from the instantiation of the pattern where the pack is declared.

The pattern of a function parameter pack is a parameter-declaration without ellipsis because it's defined as the following:
temp.variadic#4

A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list (described below). The form of the pattern depends on the context in which the expansion occurs. Pack expansions can occur in the following contexts:

  • [...]
  • In a function parameter pack ([dcl.fct]); the pattern is the parameter-declaration without the ellipsis.

A usual parameter-declaration consists of :

  • attribute-specifier-seq (opt) decl-specifier-seq declarator
  • attribute-specifier-seq (opt) decl-specifier-seq declarator = initializer-clause
  • attribute-specifier-seq (opt) decl-specifier-seq abstract-declarator(opt)
  • attribute-specifier-seq (opt) decl-specifier-seq abstract-declarator (opt) = initializer-clause

In any case , the decl-specifier-seq is not an optional component.

In this example

template<typename...T>
void func(T...args){
}

T...args is a function parameter pack, thereof, T args is its pattern. So my issues is, why the element generated from instantiation of a pattern of a function parameter pack is id-expression, However the id-expression is only a part of declarator of a parameter-declaration.

2 Answers

I try to answer this question, To understand these sentences, These sentences are necessary to split to several portions.

  1. A function parameter pack is a function parameter that accepts zero or more function arguments.
What is a function parameter pack?

In c++17 standard, it says:

dcl.fct#16

A declarator-id or abstract-declarator containing an ellipsis shall only be used in a parameter-declaration. Such a parameter-declaration is a parameter pack. When it is part of a parameter-declaration-clause, the parameter pack is a function parameter pack.

It sounds like a parameter-declaration where declarator-id or abstract-declarator containing an ellipsis and such a parameter-declaration appears in parameter-declaration-clause, such a parameter-declaration is a function parameter pack. Right?

Now, we see what the latest draft says:

dcl.fct#21

A declarator-id or abstract-declarator containing an ellipsis shall only be used in a parameter-declaration. When it is part of a parameter-declaration-clause, the parameter-declaration declares a function parameter pack.

It says a parameter-declaration where declarator-id or abstract-declarator containing an ellipsis and such a parameter-declaration appears in parameter-declaration-clause, as far as here, they are the same, however, the difference is here, such parameter-declaration declares a function parameter pack. It means T...args declares a function parameter pack.

  1. A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list... Pack expansions can occur in the following contexts:
  • In a function parameter pack ([dcl.fct]); the pattern is the parameter-declaration without the ellipsis.

The sentence means a pack expansion occurred in a context that is a function parameter pack, the pattern is the parameter-declaration without the ellipsis. Informally, for this case T...args, thereof T... denotes a pack expansion and the pattern of T...args is T args.

The instantiation of a pack expansion...

  1. if the pack is a function parameter pack, the element is an id-expression designating the function parameter that resulted from the instantiation of the pattern where the pack is declared.

About the third bullet, this pack doesn't denote T, it is a stuff declared by a parameter-declaration as the analysis of the first bullet. Another important point to understand this sentence is function parameter that resulted from the instantiation of the pattern where the pack is declared, As the aforementioned, the pattern is T args where the pack is declared. So, the emphasized sentence means function parameter is the result from these instantiations of pattern T args of pack expansion T...args, Now it confirms to the second bullet, and for some case like postfix-expression(args...), The pack args is used to be a pattern of such pack expansion and the instantiation of such pack expansion would be the id-expression designating the function parameter which from the instantiation of the pattern T args.

In that pack expansion, T and args are expanded (even as the latter is being declared as a pack); as such, the resulting parameter-declarations have the form T1 args1,T2 args2,… and are properly equipped with a decl-specifier.

Related