enable_if cannot be used to disable this declaration

N is not a dependent non-type template parameter; [temp.dep.temp]/p2

A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is value-dependent.

Therefore instead of a substitution failure occurring, the error is emitted directly from the ill-formed code.


The other answers are correct about why the error happens at the template definition rather than the instantiation.

I need an error to be thrown when trying to instantiate something like `more_than_99 <0> x;' on the line where I try to instantiate it. Something like "hey, this type doesn't exist".

How about something like this?

template <unsigned int N, bool B = (N>=100)>
struct more_than_99;

template <unsigned int N>
struct more_than_99<N,true>
{};

int main()
{
    more_than_99 <0> c; // error: implicit instantiation of undefined template 'more_than_99<0, false>'
}

To make it a bit more robust, and to attempt to prevent accidentally instantiating more_than_99<0,true>, this also works (C++11):

template <unsigned int N, bool B>
struct _impl_more_than_99;

template <unsigned int N>
struct _impl_more_than_99<N,true>
{};

template <unsigned int N>
using more_than_99 = _impl_more_than_99<N, (N>=100)>;

int main()
{
    more_than_99 <0> c; // error: implicit instantiation of undefined template '_impl_more_than_99<0, false>'
}

Although the error message references the _impl_ type.

You could hide the _impl_ in a detail namespace or something, and just document the more_than_99 alias as if it were the actual type.

However, you will not be able to prevent malicious instantiation of _impl_more_than_99<0,true>.