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


    template <typename...>
    using void_t = void;
    
    template <typename T, template <typename> class D, typename = void>
    struct detect : std::false_type {};
    
    template <typename T, template <typename> class D>
    struct detect<T, D, void_t<D<T>>> : std::true_type {};
    
    template <typename T>
    using has_m = decltype(std::declval<T>().m());
    

    template<typename T>
    struct Derived : public T
    {
         void m(std::true_type) { T::m(); }
         void m(std::false_type) {  std::cout<<"Derived\n"; }
         void m() { return m(detect<T, has_m>{}); }
    };

struct Base0 { };
struct Base1 { void m() { std::cout<<"Base1\n"; } };

int main(){
  Derived<Base0> d0;
  d0.m(); //should print "Derived"
  Derived<Base1> d1;
  d1.m(); //should print "Base1"
}