#include <iostream>
#include <type_traits>

using namespace std;

class CBase{
public:
    void basefunc(){
        cout << "basefunc" << endl;
    }
};


template<typename T,bool is_derived_from_base>
class Hoge_impl; // 何も定義しない

// 特殊化
template<typename T>
class Hoge_impl<T,true>{
    T t;
public:
    void func(){
        t.basefunc();
    }
};

template<typename T>
class Hoge : private Hoge_impl<T,std::is_base_of<CBase,T>::value>{
public:
    using Hoge_impl<T,std::is_base_of<CBase,T>::value>::func;
};

class CDerived1 : public CBase{
};
class CDerived2 : public CBase{
};
class CNotDerived{
};

int main()
{
    //これは通る。
    Hoge<CDerived1> hoge1;
    Hoge<CDerived2> hoge2;
    //が、これは通らない。
    //Hoge<CNotDerived> hoge3;
    // Hoge<int> hoge4;

    hoge1.func();
    hoge2.func();
    // hoge3.func();
    // hoge4.func();
    return 0;
}