Skip to main content
gamedev.net
🔒 Locked

template inheritance?

Started by The C modest god 3 replies 1.4k views
Original Post
The C modest god
The C modest god
Lets say I have the code:


template <class T>
class A {
};

class B {
};

class C: public B{
}

class D {
};

void foo (A<B> arg)
{
}

A<C> test;
A<D> test2;

foo (test) // <= Ok
foo (test2) // <= Compilation error


So I need a cpy ctr from class C to class B? However, I want to have the cpy ctr only between inherited classes and not between any two calsses. Is this possible?
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower. Quote: Original post by Toolmaker Quote:
Fruny
Fruny
Even though B and C are related via inheritance, A<b> and A<C> are not. B and C's constructors are not the problem, A's are. What you want is a conversion constructor from A<U> to A<T> where U derives from T. The simplest solution I can think of is to use Boost's type traits metafunctions along with enable_if

template <class T> class A{public:   template<class U> A(const A<U>& a, typename enable_if< is_base_of<T,U> >::type* dummy = 0)   {      // stuff   }};
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
The C modest god
The C modest god
Quote:
Original post by Fruny
Even though B and C are related via inheritance, A<b> and A<C> are not. B and C's constructors are not the problem, A's are. What you want is a conversion constructor from A<U> to A<T> where U derives from T. The simplest solution I can think of is to use Boost's type traits metafunctions along with enable_if

template <class T> class A{public:   template<class U> A(const A<U>& a, typename enable_if< is_base_of<T,U> >::type* dummy = 0)   {      // stuff   }};

I dont use boost.
The problem is, if I have a conversion constructor between the two types, will I also get a compilation error of two types which do not inherit one of the other?
Is there a way to do this in CPP without boost?
How does boost achieve this?

Edit: actually it is a lot more easier then I thought.
I am doing my own "smart" pointers (I call them defense pointers).
So basically a pointer class would look like:
template <class T>class Pointer {   template <class M>   friend Pointer<M>;   public:        template <class M>        Pointer<T> & operator= (const Pointer<M> & Source);   private:        T * pData;}template <class T>template <class M>Pointer<T> &Pointer<T>::operator= (const Pointer<M> & Source){   this->pData = Source.pData; // <=compilation error!}class A {};class B: public A {};class C {};Pointer<A> a;Pointer<B> b;Pointer<C> c;a = b; //<= OKa = c //<= Compilation error


So if I will get the required compilation error inside the operator= for classes that do not inherit each other.
I havnt tested this yet, but I think it should work.
What do you think?
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower. Quote: Original post by Toolmaker Quote:
Fruny
Fruny
Quote:
Original post by The C modest god
I dont use boost.


[rolleyes][boost]

Quote:
The problem is, if I have a conversion constructor between the two types, will I also get a compilation error of two types which do not inherit one of the other?


Yes.

Quote:
Is there a way to do this in CPP without boost?


Yes, obviously.

Quote:
How does boost achieve this?


See the explanation for yourself.

Quote:
Edit: actually it is a lot more easier then I thought.


Have you covered all the corner cases?

Quote:
I havnt tested this yet, but I think it should work.
What do you think?


It's your code, not mine. So long as you're happy with it...
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Polymorphic OOP
Polymorphic OOP
Quote:
Original post by Fruny
template <class T> class A{public:   template<class U> A(const A<U>& a, typename enable_if< is_base_of<T,U> >::type* dummy = 0)   {      // stuff   }};

I wouldn't use is_base_of there. is_base_of yields if the left type is a base of the right type, regardless of whether public, private, or protected inheritance were used. As well, if the left type is less qualified than the right, your template would still be instantiated, which again is a mistake. Finally, it will fail to exhibit the desired behavior when T and U are pointers. Really, what you want to do is check whether or not the pointers are convertible.

template <class T> class A{public:   template<class U> A(const A<U>& a, typename enable_if< is_convertible< U*, T* > >::type* dummy = 0 )   {      // stuff   }};

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.