Document number: N3270=11-0040
Author: Doug Gregor
Date: 2011-03-22
Reply-To: doug.gregor@gmail.com

Variadic Templates: Wording for Core Issues 778, 1182, and 1183.

This paper addresses the following three issues with variadic templates:

Proposed resolution:

  1. Change 5.3.3 [expr.sizeof] paragraph 5 as follows:

  2. The identifier in a sizeof... expression shall name a parameter pack. The sizeof... operator yields the number of arguments provided for the parameter pack identifier. The parameter pack is expanded (14.5.3 [temp.variadic]) by the sizeof... operator A sizeof... expression is a pack expansion (14.5.3 [temp.variadic]). [Example:...
  3. Change 8.3.5 [dcl.fct] paragraph 13 as follows:

  4. 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 (14.5.3 [temp.variadic]). When it is part of a parameter-declaration-clause, the parameter pack is a function parameter pack (14.5.3 [temp.variadic]). [Note: Otherwise, the parameter-declaration is part of a template-parameter-list and the parameter pack is a template parameter pack; see 14.1 [temp.param]. —end note] The type T of the declarator-id of the function parameter pack shall contain a template parameter pack; each template parameter pack in T is expanded by the function parameter pack A function parameter pack is a pack expansion (14.5.3 [temp.variadic]). [Example:...
  5. Change 14.1 [temp.param] paragraph 15 as follows:

  6. 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 (8.3.5 [dcl.fct]), then the template-parameter is a template parameter pack (14.5.3 [temp.variadic]). 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> 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
    
  7. Change 14.5.3 [temp.variadic] paragraphs 4-6 and add a new paragraph 7 as follows:

  8. A pack expansion is a sequence of tokens that names one or more parameter packs, followed by an ellipsis. The sequence of tokens is called the pattern of the expansion; its syntax 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:

    [Example:...

    A parameter pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion. An appearance of the name of a parameter pack is only expanded by the innermost enclosing pack expansion. The pattern of a pack expansion shall name one or more parameter packs that are not expanded by a nested pack expansion; such parameter packs are called unexpanded parameter packs in the pattern. All of the parameter packs expanded...

      ...
      void g(Args ... args) {  // OK: Args is expanded by the function parameter pack args
      ...
    

    The instantiation of an a pack expansion that is not a sizeof... expression produces a list...

    The instantiation of a sizeof... expression (5.3.3 [expr.sizeof]) produces an integral constant containing the number of elements in the parameter pack it expands.