1

I am trying to build a class template that inherits the class. If the class template is given a primitive type as template argument, then it gives an illegal inheritance error. I tried doing

template <class Class_>
struct EndianGuard_ : public Class_ {
  EndianGuard_ () {
    cout << "Guarding a Class" << endl;
  }
}

template <typename PrimitiveType_>
struct EndianGuard_ {
  EndianGuard_ (PrimitiveType_ Value) : Value(Value) {
    cout << "Guarding a primitive type" << endl;
  }
  PrimitiveType_ Value;
}

of course I knew it doesn't work that way but I am desperate. How can I differentiate primitive type and a structure?

Necktwi
  • 2,483
  • 7
  • 39
  • 62
  • So you want to inherit only if Class_ is not a primitive type? – DeiDei Dec 28 '17 at 14:15
  • also wrap the primitive types – Necktwi Dec 28 '17 at 14:17
  • Do you mean if you use int, or double, for example, as the type for 'PrimativeType' it doesn't work? – ttemple Dec 28 '17 at 14:20
  • Possible duplicate of [Identifying primitive types in templates](https://stackoverflow.com/questions/580922/identifying-primitive-types-in-templates) (which uses `std::is_fundamental`) or [Is there a way to specialize a template to target primitives?](https://stackoverflow.com/questions/11287043/is-there-a-way-to-specialize-a-template-to-target-primitives) (which uses its inverse, `std::is_class`) – underscore_d Dec 28 '17 at 14:24

1 Answers1

3

This is where a template specialization comes in handy.

#include <type_traits>

template <class Class_, bool = std::is_class<Class_>::value>
struct EndianGuard_ : public Class_ 
{
    // inherit if class
};

template <class Class_>
struct EndianGuard_<Class_, false> 
{
    // don't inherit if not a class
};

struct foo {};

int main() 
{
    EndianGuard_<int> f; //ok
    EndianGuard_<foo> f2; // ok
}

If std::is_class<Class_>::value evaluates to false, the specialization kicks in and you can handle the non-class type. Other conditions can be added for more restriction.
As a side note, it's probably best to handle the std::is_final case, since you can't inherit from a final class.

DeiDei
  • 10,205
  • 6
  • 55
  • 80