This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


2383. Variadic member functions of variadic class templates

Section: 13.2  [temp.param]     Status: NAD     Submitter: Daveed Vandevoorde     Date: 2018-07-18

The intended treatment of an example like the following is not clear:

  template<class ...Types> struct Tuple_ { // _VARIADIC_TEMPLATE
    template<Types ...T> int f() {
      return sizeof...(Types);
    }
  };

  int main() {
    Tuple_<char,int> a;
    int b = a.f();
  }

According to 13.2 [temp.param] paragraph 19,

If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a pack (9.3.4.6 [dcl.fct]), then the template-parameter is a template parameter pack (13.7.4 [temp.variadic]). A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded 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 packs is a pack expansion. A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same template-parameter-list.

with the following example:

  template <class... T>
    struct value_holder {
      template <T... Values> struct apply { }; // Values is a non-type template parameter pack
  };                                           // and a pack expansion

There is implementation divergence on the treatment of the example, with some rejecting it on the basis that the arguments for Tuple_::f cannot be deduced, while others accept it.

Rationale (December, 2018):

The example is ill-formed because the packs have different sizes: Types has 2, T has 0 (from the call).