Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are multiple non-type template parameter packs allowed?

[temp.param] p11 says (in N4527):

(...) 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 of the function template or has a default argument

In the context of non-type template parameter packs, there can't be default arguments,
so what exactly needs to be deduced for the packs (just the type, or the values, too)?

i.e. I'm wondering if this is allowed by the standard (C++11, 14 or 1z):

template<typename T, T... A, T... B>
void foo(T) {}

The first pack's values could be explicitly specified, but the second pack is "unreachable" and would always be empty if I'm not mistaken.

clang++-3.6 and g++-5.2 seem to accept these empty unreachable packs (even non non-type packs), but VC++ 14.0 refuses them with the error:

error C3547: template parameter 'B' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'foo'

like image 771
melak47 Avatar asked Jul 29 '15 09:07

melak47


People also ask

How many parameter are legal for non-type template?

Correct Option: A The following are legal for non-type template parameters: integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.

Can we use non-type parameters as argument templates?

A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.

What is non-type template parameters?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

What can be passed by non-type template parameters during compile time?

What can be passed by non-type template parameters during compile time? Explanation: Non-type template parameters provide the ability to pass a constant expression at compile time. The constant expression may also be an address of a function, object or static class member.


1 Answers

No, it not allowed by the standard. From [temp.param]:

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 of the function template or has a default argument (14.8.2). [Example:

template<class T1 = int, class T2> class B;    // error

// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { }  // error
template<class... T, class U> void g() { }     // error

—end example ]

In your case, ...B cannot be deduced (as there's nothing to deduce it from) and it has no default argument.

so what exactly needs to be deduced for the packs (just the type, or the values, too)?

For example, if your foo was:

template <size_t... A, size_t... B>
void foo(std::index_sequence<B...> );

...A is followed by ...B, but ...B can be deduced, so that's allowed. Similarly:

template <typename T, T... A, T B = 0>
void foo();

is fine, as B has a default argument.

like image 176
Barry Avatar answered Oct 30 '22 18:10

Barry