It should be:
template <typename T, TM, T N> struct GCD_pair<T, M, N, typename std::enable_if<(M % N != 0)>::type> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
Since you are using C ++ 14, you can also simplify it using std::enable_if_t :
template <typename T, TM, T N> struct GCD_pair<T, M, N, std::enable_if_t<(M % N != 0)>> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
In both cases, if the condition is applied (M % N != 0) , both the primary template and the specialization are valid after the instance is created, but the specialization, and therefore, is more specialized and, therefore, selected. On the other hand, if the condition does not apply, the specialization is silently discarded due to sfinae rules, but the primary template is still valid and selected in this way.
Note that the type in typename std::enable_if<(M % N != 0)>::type is void when the condition is true.
Because of this, the list of template templates will be theoretically:
template <typename T, TM, TN, void> struct GCD_pair<T, M, N, void>: std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
However, void not allowed as a parameter of the non-type type template.
Finally, from the standard we have:
Partial specialization corresponds to this actual list of template arguments, if partial template arguments can be deduced from the actual list of template arguments
also:
If the arguments of the partial specialization template cannot be deduced due to the structure of its template-parameter-list and template identifier, the program is poorly formed.
In your case, the fourth specialization parameter cannot be displayed for obvious reasons. Even if it was valid (and it is not, because it leads to void , as mentioned), what you get is a type or non-type parameter for which you do not have an actual type or value.
Suppose you have the following specialization:
template <typename T, TM, TN, int> struct GCD_pair<T, M, N, void> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
How could the compiler output the value for the last template parameter?
It cannot and that is more or less your case. Probably, this should soon detect the fact that the parameter list is poorly formed if the condition on std::enable_if valid, in any case both are errors, and you get one of them from the compilation phase.
What will be useful to you is something like this:
template <typename T, TM, TN, typename = std::enable_if_t<(M % N != 0)>> struct GCD_pair<T, M, N, void> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
Or that:
template <typename T, TM, TN, std::enable_if_t<(M % N != 0)>* = nullptr> struct GCD_pair<T, M, N, void> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
In any case, both of them are invalid, since the default arguments are not allowed in partial specialization.