Default template arguments are not part of the signature of a function template. So in your example you have two identical overloads of less, which is illegal. clang complains about the redefinition of the default argument (which is also illegal according to §14.1/12 [temp.param]), while gcc produces the following error message:
error: redefinition of 'template<class T, class> bool less(T, T)'
To fix the error move the enable_if expression from default argument to a dummy template parameter
template <class T,
typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
template <class T,
typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
Another option is to use enable_if in the return type, though I feel this is harder to read.
template <class T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
less(T a, T b) {
// ....
}
template <class T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
less(T a, T b) {
// ....
}