3

Is it possible to derive all template instantiations that have a derived class as their argument from the instantiation that has the base class as its argument?

In code:

class Base{};

class Derived1 : Base{};

class Derived2 : Base{};

template<typename T>
class Templ /*: Templ<Base> if T derives from Base*/ 
{};

How would one do that?

iFreilicht
  • 13,271
  • 9
  • 43
  • 74
  • What must the class derive from if the argument does not derive from something? Must it "in general" derive from Templ if Derive inherits from Base, where base is an arbitrary type, or is is very specific. – Werner Erasmus Jul 31 '14 at 13:56

2 Answers2

4

Make a specialization for Templ<Base>, and then use SFINAE along with std::is_base_of to derive a separate specialization from Templ<Base>.

template<typename T, typename V = void>
class Templ 
{};

template<>
class Templ<Base>
{};

template<bool B, typename R = void>
using enable_if_t = typename std::enable_if<B, R>::type;

template<typename T>
class Templ<T, enable_if_t<std::is_base_of<Base, T>::value>>
    : public Templ<Base>
{};
David G
  • 94,763
  • 41
  • 167
  • 253
  • If I understand correctly, this tries to instantiate the specialization `Templ>`. So if `enable_if` has no member typedef `type`, the substitution fails and the template is not specialized. But if `enable_if` does have `type`, the substitution succeeds and therefore the template is specialized and derived from `Templ`, correct? – iFreilicht Jul 31 '14 at 14:04
  • 2
    There's no need to specialize `Templ` if you exclude `Base` from the condition a la `enable_if_t::value && !std::is_same::value>`. – Casey Jul 31 '14 at 15:00
1

It depends what exactly you want to do. If you want this to work only for some specific, known baseclass, it can easily accomplished, e.g. like in 0x499602D2's answer.

However the way I interpret your question you want to have a template which derives from the instantiation for it's arguments baseclass, whichever that might be. This is not possible in standard c++ (yet), since there is no way to query what class a specific type is derived from, only if it is derived from a specific classes. For more on this (and possible future solutions look at this question.

Community
  • 1
  • 1
Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • I would *like* to have it work for arbitrary base classes, but 0x499602D2's solution is good enough and seems to work. Thanks for the link, I'm getting more and more exited for C++14 every other day! – iFreilicht Jul 31 '14 at 13:48
  • @iFreilicht: Well, afaik the mentioned functionality is not part of I too am eagerly awaiting those features. However afaik it won't be in C++14. This is worked on by the Reflection study group of the standard comittee, which doesn't have a proposal ready yet iirc, so I wouldn't expect anything before 2017, maybe later. – Grizzly Jul 31 '14 at 13:58