This is a follow-up on this question.
Consider the following code:
#include <type_traits>
template<typename T, typename... P, typename U = std::enable_if_t<std::is_integral<T>::value>>
void f() { static_assert(sizeof...(P) == 0, "!"); }
int main() {
f<int>();
}
It compiles, but according to [temp.res]/8 it is ill-formed, no diagnostic required because of:
every valid specialization of a variadic template requires an empty template parameter pack
Now consider this slightly different example:
#include <type_traits>
template<typename T, typename... P, typename U = std::enable_if_t<std::is_integral<T>::value>>
void f() { static_assert(sizeof...(P) == 0, "!"); }
template<>
void f<int, int>() { }
int main() {
f<int, int>();
}
In this case a valid full explicit specialization exists for which the parameter pack is not empty.
Does this suffice to say that the code is no longer ill-formed?
Note: I'm not looking for alternative ways like putting the std::enable_if_t
in the return type or similar.
[temp.res]/8 talks about template-declarations, not the entity. That is, it talks about primary templates and partial specializations individually; these "templates" must each have a valid specialization subject to the rules. Otherwise, the first bullet in that paragraph would have to be interpreted in the same manner, which definitely doesn't give it its intended meaning.
template <typename T>
void f() {T+0;} // wouldn't be allowed to diagnose this, because there could be an
// explicit specialization that doesn't contain this statement...?
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