std::enable_if
doesn't have to be in the return type, as of C++11 it can be part of the template parameters.
So your equivalent functions can be (or, well, something to this effect):
enum class enabler_t {};
template<typename T>
using EnableIf = typename std::enable_if<T::value, enabler_t>::type;
//This function is chosen when an integral type is passed in
template<class T, EnableIf<std::is_integral<T>>...>
auto function(T t) {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T, EnableIf<std::is_floating_point<T>>...>
auto function(T t) {
std::cout << "floating" << std::endl;
return;
}
It can also be a parameter in the function:
//This function is chosen when an integral type is passed in
template<class T>
auto function(T t, EnableIf<std::is_integral<T>>* = nullptr) {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T>
auto function(T t, EnableIf<std::is_floating_point<T>>* = nullptr) {
std::cout << "floating" << std::endl;
return;
}
This will keep the automatic type deduction and SFINAE.