Skip to content

CWG2994 [temp.param] Unintentional restrictions on parameters packs which are also pack expansions #666

Description

@eisenwave

Reference (section label): [temp.param] paragraph 14

Issue description

There is implementation divergence in the following example:

template <class Head, class... Tail>
struct test {
    template <Tail..., Head>
    static void make() { } // MSVC error C3547: template parameter 'unnamed-parameter' cannot be used
                           // because it follows a template parameter pack and
                           // cannot be deduced from the function parameters of 'test<Head,Tail...>::make'
};

int main() {
    test<char, int, float>::make<4, 6.f, 'a'>();
}

Clang permits this example, but MSVC abides by [temp.param] paragraph 14, sentence 3:

A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).

The intent of the restriction is that it is not permitted to write template parameter lists for which it is impossible to provide all arguments. However, [temp.param] paragraph 17 states that Tail... is not just a parameter pack but also a pack expansion. Considering that it expands to int, float in this example, following this restriction literally is nonsensical; it is clearly possible to provide (non-type) template-arguments to test<char, int, float>::make because it accepts exactly three.

Suggested resolution

Update [temp.param] paragraph 14 as follows:

A template parameter pack of a function template shall not be followed by another template parameter P unless
  • that template parameter P can be deduced from the parameter-type-list ([dcl.fct]) of the function template, or
  • P has a default argument ([temp.deduct]), or
  • that template parameter pack is also a pack expansion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions