Да, их подписи одинаковы;аргументы шаблона по умолчанию не являются частью сигнатуры шаблона функции.
Вы можете изменить их на
// the 2nd non-type template parameter are different
template<typename T, std::enable_if_t<std::is_default_constructible<T>::value>* = nullptr>
auto foo(T&& val) {
return 0;
}
template<typename T, std::enable_if_t<!std::is_default_constructible<T>::value>* = nullptr>
auto foo(T&& val) {
return 0;
}
Или
// the return type are different
template<typename T>
std::enable_if_t<std::is_default_constructible<T>::value, int> foo(T&& val) {
return 0;
}
template<typename T>
std::enable_if_t<!std::is_default_constructible<T>::value, int> foo(T&& val) {
return 0;
}