#include <type_traits>
#include <utility>
#include <iostream>

template <typename T, typename = void>
struct foo_impl {};

template <typename T>
inline auto foo(T x) -> decltype(foo_impl<T>{}(x))
{
        return foo_impl<T>{}(x);
}

template <typename T>
struct foo_impl<T,typename std::enable_if<std::is_integral<T>::value>::type>
{
        void operator()(T) {}
};

template <typename T>
struct has_foo
{
        struct yes {};
        struct no {};
        template <typename T1>
        static auto test(T1 x) -> decltype(foo(x),void(),yes{});
        static no test(...);
        static const bool value = std::is_same<yes,decltype(test(std::declval<T>()))>::value;
};

template <typename T>
struct foo_impl<T,typename std::enable_if<has_foo<unsigned>::value && std::is_floating_point<T>::value>::type>
{
        void operator()(T) {}
};

int main()
{
        std::cout << has_foo<float>::value << '\n';
        std::cout << has_foo<int>::value << '\n';
        foo(3.1);
}