Error when using Inheritance in templates.

V

Vinesh S

Hello all,

I wanted to use inheritance in the typename.

for. eg.
template <class T>
class Listener
{
.....
T* ptr;

};

and in the main ...

Listener<BaseAdapter>* listenerPtr1 = new
Listener<ChildAdapter>(<param>);

where BaseAdapter -> ParentClass
ChildAdapter-> Child class derived from BaseAdapter.

==================================================

when i tried to compile, it throws an error
saying
error: cannot convert ‘Listener<ChildAdapter>*’ to
‘Listener<BaseAdapter>*’ in initialization

How can i get around this problem?
As i want a class template whose typename is a base class and the
instances use the child class....
is this possible ?

Waiting to hear from you guys,

Thanks,

Vinesh.S





When i try this in my program, it throws a compilation error.
 
D

Dombo

Op 28-Aug-11 10:11, Vinesh S schreef:
Hello all,

I wanted to use inheritance in the typename.

for. eg.
template<class T>
class Listener
{
....
T* ptr;

};

and in the main ...

Listener<BaseAdapter>* listenerPtr1 = new
Listener<ChildAdapter>(<param>);

where BaseAdapter -> ParentClass
ChildAdapter-> Child class derived from BaseAdapter.

==================================================

when i tried to compile, it throws an error
saying
error: cannot convert ‘Listener<ChildAdapter>*’ to
‘Listener<BaseAdapter>*’ in initialization

This is to be expected since as far as inheritance is concerned the
How can i get around this problem?

There are several ways I can think of, but it is hard to tell which one
would be more appropriate without having a bit more information about
what you are trying to accomplish.
As i want a class template whose typename is a base class and the
instances use the child class....
is this possible ?

The question is why are you using a template class here? If ChildAdapter
is derived from BaseAdapter why wouldn't a non-templated Listener class
which has a BaseAdapter pointer suffice?
 
N

Noah Roberts

Hello all,

I wanted to use inheritance in the typename.

for. eg.
template <class T>
class Listener
{
....
T* ptr;

};

and in the main ...

Listener<BaseAdapter>* listenerPtr1 = new
Listener<ChildAdapter>(<param>);

where BaseAdapter -> ParentClass
ChildAdapter-> Child class derived from BaseAdapter.

You could write a generic constructor that either asserts failure or
uses SFINAE to disappear when inappropriate:

assert version:
template < typename TT >
Listener(Listener<TT> const& other_type)
: ptr(other_type.ptr)
{
static_assert(is_convertible<TT,T>::value, "Only use with
convertible types.");
}

I might have the argument order wrong with is_convertible. If you're
not using a C++0x compiler or are not ready to use that language, use
boost's type_traits library and BOOST_STATIC_ASSERT.

This one uses boosts enable_if.

template < typename TT>
Listener(Listener<TT> const& ot, typename
boost::enable_if<is_convertible<TT,T>>::type * = 0)
: ptr(ot.ptr)
{}

All of these constructs can be created yourself. The only one that is
mildly difficult is the is_convertible. You'll need the SFINAE
function overload trick if you have to do it yourself.

The key here is that the generic constructor will allow you to convert
from the unrelated type Listener<Derived> to Listener<Base>. The
safety measures allow you to do so secure that it'll only be used for
non-evil ends. They might not actually be necessary since attempting
to assign the ptr itself should blow up when it's an invalid
conversion. On the other hand, the static assert is slightly more
informative about what's going on
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top