Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are checked guard parameter packs cause of ill-formed programs in case of specializations?

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.

like image 407
skypjack Avatar asked Nov 28 '16 10:11

skypjack


1 Answers

[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...?
like image 135
Columbo Avatar answered Oct 25 '22 14:10

Columbo