I have a Container
class that holds objects whose type may be derived from any combination of some base classes (TypeA
, TypeB
, etc.). The base class of Container
has virtual methods that return a pointer to the contained object; these should return nullptr
if the contained object isn't derived from the expected class. I would like to selectively override the base's methods based on Container
's template parameter. I tried using SFINAE as follows, but it doesn't compile. I would like to avoid specializing Container
for every possible combination because there could be many.
#include <type_traits>
#include <iostream>
using namespace std;
class TypeA {};
class TypeB {};
class TypeAB: public TypeA, public TypeB {};
struct Container_base {
virtual TypeA* get_TypeA() {return nullptr;}
virtual TypeB* get_TypeB() {return nullptr;}
};
template <typename T>
struct Container: public Container_base
{
Container(): ptr(new T()) {}
//Override only if T is derived from TypeA
auto get_TypeA() -> enable_if<is_base_of<TypeA, T>::value, TypeA*>::type
{return ptr;}
//Override only if T is dervied from TypeB
auto get_TypeB() -> enable_if<is_base_of<TypeB, T>::value, TypeB*>::type
{return ptr;}
private:
T* ptr;
};
int main(int argc, char *argv[])
{
Container<TypeA> typea;
Container<TypeB> typeb;
Container<TypeAB> typeab;
cout << typea.get_TypeA() << endl; //valid pointer
cout << typea.get_TypeB() << endl; //nullptr
cout << typeb.get_TypeA() << endl; //nullptr
cout << typeb.get_TypeB() << endl; //valid pointer
cout << typeab.get_TypeA() << endl; //valid pointer
cout << typeab.get_TypeB() << endl; //valid pointer
return 0;
}