Try this instead:
#include <type_traits> #include <iostream> template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr> void my_function() { std::cout << "N >= 100" << std::endl; } template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr> void my_function() { std::cout << "N < 100" << std::endl; } int main() { my_function<42>(); my_function<100>(); } Template default parameters do not participate in the overloadTemplate default parameters do not participate in the overload (and hence SFINAE does not apply). On the other hand, in the snippet above, the dependent template non-type parameter is on the left hand side of the assignment, so SFINAE kicks in.