#include <iostream>
#include <type_traits>

struct Dummy {};

template<typename T>
class Base {};

class DerivedInt : public Base<int> {};

class DerivedDummy : public Base<Dummy> {};

template<typename E>
class DerivedGeneric : public Base<E> {};

template <class T>
std::true_type is_derived_from_base_t_impl(const Base<T>* impl);

std::false_type is_derived_from_base_t_impl(...);

template <class Derived>
using is_derived_from_base_t = decltype(is_derived_from_base_t_impl(std::declval<Derived*>()));

int main()
{
    std::cout<< is_derived_from_base_t< DerivedInt >() <<"\n";
    std::cout<< is_derived_from_base_t< DerivedDummy >() <<"\n";
    std::cout<< is_derived_from_base_t< DerivedGeneric<float> >() <<"\n";
    std::cout<< is_derived_from_base_t< float>() <<"\n";
    return 0;
}
