mercredi 25 mai 2016

Enable if/else class member template instantiation

Can anyone tell my how to enable if/else class member template based on different derived classes from pre-defined base set? Let me use the following example:

enum class Type {
  TYPEA,
  TYPEB
};

// Predefined in libraries.
class BaseA {...};
class BaseB {...};

class Foo {
  template <typename Derived, Type type>
  void foo();
};

// User-derived
class DerivedA : public BaseA {};
class DerivedB : public BaseB {};

Normally we need two template typenames for calling the member foo.

Foo obj;
obj.foo<DerivedA, Type::TypeA>()
obj.foo<DerivedB, Type::TypeB>();

However, this native approach seems lengthy because the second template argument Type::TypeA and Type::TypeB can obviously be deduced by compiler through the first argument DerivedA and DerivedB, if they are derived from pre-defined base properly. I notice that c++11 provides is_base_of template but I am not sure how to use it in my case. To be more specific, below is the expected solution:

obj.foo<DerivedA>();  // Automatically deduce type = Type::TypeA
obj.foo<DerivedB>();  // Automatically deduce type = Type::TypeB

And if the compile fails to deduce the Type from the first typename, it should it just goes back to the normal declaration obj.foo<MyClass, MyType> where MyType is either Type::TypeA or Type::TypeB.

Aucun commentaire:

Enregistrer un commentaire