简体   繁体   中英

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?

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!

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM