The relevant rule is [temp.res]/8:
Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:
Both static_assert
s in the example cause the program to be ill-formed, but no diagnostic is required. Compilers are certainly allowed to evaluate arbitrarily complex expressions to attempt to prove that no valid specialization could be generated, but they are not required that they do so. false
is certainly an easy case to immediately verify, so it's not surprising that it is diagnosed.
A common approach to the desire to always issue a diagnostic is:
// never specialize me!
template <typename T>
struct always_false : std::false_type { };
template <typename T>
constexpr bool always_false_v = always_false<T>::value;
template<typename T, typename = void>
struct S {
static_assert(always_false_v<T>, "Unconditional error");
};
always_false
could hypothetically be specialized on a particular T
to yield true_type
, so there could hypothetically be a valid specialization S<T>
. But don't let anybody actually do that.