Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Class inheritance and templates

I would like to write in my C++ program something like:

class A {
 public:
   void a();
}

template <class B extends A>
class C {
 B instance;
}

Is this possible? In other words: does C++ allow me to say that the class within a template is a subclass of something else?

like image 275
jrbn Avatar asked Nov 28 '13 12:11

jrbn


2 Answers

Define a meta-function called extends (which is just a sugar-coated name) as:

template<typename D, typename B>
using extends = std::is_base_of<B,D>;

Then define your class as:

template <class B>
class C 
{
   //here you can check it, and generate your own error message!
   static_assert(extends<B,A>(), 
                "Constraint Violation: B doesn't derive from A.");

   B instance;
};

Or, you can write this instead:

//define it a bit differently now!
template<typename D, typename B>
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type;

template <class B, class Unused=extends<B,A>>
class C 
{
      B instance;
};

But in this case, you don't have opportunity to generate your own error message. The compiler is free to throw any error message at you which may be difficult to comprehend.

Anyway, you probably realize you can use std::is_base_of<> directly. But if you're looking for sugar-coated name, then extends sounds good!

like image 56
Nawaz Avatar answered Sep 29 '22 03:09

Nawaz


Not really in a direct way. But you can use static_assert with type_traits, like this:

static_assert(is_base_of<A,B>::value, "C<B> requires B:A");

You can put that in your constructor for example, then it will fail to compile if the requirement is not satisfied. Note that this is all C++11 stuff, but it exists in Boost long before that, or you can code it up yourself if you're really stuck (it doesn't require language support).

like image 28
John Zwinck Avatar answered Sep 29 '22 04:09

John Zwinck