#include <iostream>

template <typename T>
struct is_foo {
    private:
        template<typename U, U> struct helper{};

        template <typename Z> static auto test(Z z) -> decltype(

                helper<void (Z::*)() const,                       &Z::foo>(),
                // All other requirements follow..

                std::true_type()
                );

        template <typename> static auto test(...) -> std::false_type;

    public:
        enum { value = std::is_same<decltype(test<T>(std::declval<T>())),std::true_type>::value };
};

struct A { 
    void foo() const; 
};

struct A1 : public A {};

struct B { void foo(); };
struct C { int foo() const; };

template <typename T>
struct D : public T {};

int main() {
    std::cout << "Good examples (should print 1)\n";
    std::cout << is_foo<A>::value       << '\n';    
    std::cout << is_foo<A1>::value      << '\n';   
    std::cout << is_foo<D<A>>::value    << '\n'; 
    std::cout << is_foo<D<A1>>::value   << '\n';

    std::cout << "Bad examples (should print 0)\n";
    std::cout << is_foo<B>::value       << '\n';
    std::cout << is_foo<C>::value       << '\n';
    std::cout << is_foo<D<B>>::value    << '\n';
    std::cout << is_foo<D<C>>::value    << '\n';

    return 0;
}
