[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'
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.
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.
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? 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With