
    #include <type_traits>
    #include <iostream>
     
     
    template <typename T>
    class is_int_or_float : public std::integral_constant<bool, std::is_same<T, int>::value || std::is_same<T, float>::value> {
    };
     
     
    template<typename T, typename Enable = void> //(2)
    struct Helper {
        static void go(const T&) {
                    std::cout << "all"<< std::endl;
            }
    };
     
    template<typename T>
    struct Helper<T, typename std::enable_if<is_int_or_float<T>::value>::type> { // (3)
            static void go(const T&) {
                    std::cout << "int or float" << std::endl;
            }
    };
     
    template<typename T>
    struct Helper<T, typename std::enable_if<std::is_pointer<T>::value>::type> { // (3)
            static void go(const T&) {
                    std::cout << "pointer" << std::endl;
            }
    };
     
    template<typename T>
    void func(const T& arg) {
            Helper<T>::go(arg); // (1)
    }
    int main() {
            char c;
            int i;
            float f; 
            int* p;
            func(c);
            func(i);
            func(f);
            func(p);
    }
