#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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgRHVtbXkge307Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBCYXNlIHt9OwoKY2xhc3MgRGVyaXZlZEludCA6IHB1YmxpYyBCYXNlPGludD4ge307CgpjbGFzcyBEZXJpdmVkRHVtbXkgOiBwdWJsaWMgQmFzZTxEdW1teT4ge307Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBFPgpjbGFzcyBEZXJpdmVkR2VuZXJpYyA6IHB1YmxpYyBCYXNlPEU+IHt9OwoKdGVtcGxhdGUgPGNsYXNzIFQ+CnN0ZDo6dHJ1ZV90eXBlIGlzX2Rlcml2ZWRfZnJvbV9iYXNlX3RfaW1wbChjb25zdCBCYXNlPFQ+KiBpbXBsKTsKCnN0ZDo6ZmFsc2VfdHlwZSBpc19kZXJpdmVkX2Zyb21fYmFzZV90X2ltcGwoLi4uKTsKCnRlbXBsYXRlIDxjbGFzcyBEZXJpdmVkPgp1c2luZyBpc19kZXJpdmVkX2Zyb21fYmFzZV90ID0gZGVjbHR5cGUoaXNfZGVyaXZlZF9mcm9tX2Jhc2VfdF9pbXBsKHN0ZDo6ZGVjbHZhbDxEZXJpdmVkKj4oKSkpOwoKaW50IG1haW4oKQp7CiAgICBzdGQ6OmNvdXQ8PCBpc19kZXJpdmVkX2Zyb21fYmFzZV90PCBEZXJpdmVkSW50ID4oKSA8PCJcbiI7CiAgICBzdGQ6OmNvdXQ8PCBpc19kZXJpdmVkX2Zyb21fYmFzZV90PCBEZXJpdmVkRHVtbXkgPigpIDw8IlxuIjsKICAgIHN0ZDo6Y291dDw8IGlzX2Rlcml2ZWRfZnJvbV9iYXNlX3Q8IERlcml2ZWRHZW5lcmljPGZsb2F0PiA+KCkgPDwiXG4iOwogICAgc3RkOjpjb3V0PDwgaXNfZGVyaXZlZF9mcm9tX2Jhc2VfdDwgZmxvYXQ+KCkgPDwiXG4iOwogICAgcmV0dXJuIDA7Cn0K