Есть небольшие различия, но оба могут использоваться для SFINAE.
typename = enable_if_t<...>
формы не допускают «простых» перегрузок:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<!cond<T>::value>>
void foo(); // Error: redeclaration of same function as default are not part of signature
// Both are just template <typename, typename> void foo()
enable_if_t<cond, bool> = true
не страдает от этого:
template <typename T, enable_if_t<cond<T>::value, bool> = true>
void foo();
template <typename T, enable_if_t<!cond<T>::value, bool> = true>
void foo();
Другая проблема с typename = enable_if_t<...>
заключается в том, что использование может быть взломано:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<cond<T>::value>>
void bar(T);
foo<int>(); // Regular usage, SFINAE occurs
bar(42); // Regular usage, SFINAE occurs
bar<int>(42); // Possible usage, SFINAE still occurs
// But
foo<int, void>(); // No substitution fails here, so no SFINAE
bar<int, void>(42); // No substitution fails here, so no SFINAE