I have the following code that doesn't compile.
class Base {
public:
virtual ~Base() { };
};
class Derived : public Base { };
class NotDerived { };
template <typename T>
class Group { };
int main() {
Group<Base> *g = NULL;
g = new Group<Base>(); // Works
g = new Group<Derived>(); // Error, but I want it to work
g = new Group<NotDerived>(); // Error, as expected
}
I understand that this won't compile because g
is a different type than Group<Derived>
. To make this work in Java I would do something such as Group<? extends Base> g
, but C++ doesn't have that keyword as far as I know. What can be done?
Edit: I would like to clarify that I do not want it possible to set types not derived from Base
as g
. I have updated my example to explain this.
Edit 2: There are two solutions to my problem. Dave's I found to be simple and easy to define. But Bowie's (along with Mark's additions) suited my needs better.
The classes Group<Base>
and Group<Derived>
are entirely unrelated, different classes. Pointers to them are not convertible in either direction.
If you need runtime-polymorphic behaviour, your class template Group
could derive from a common (non-templated) base class:
class Group // base
{
virtual ~Group() { }
};
template <typename T>
class ConcreteGroup : public Group
{
// ...
T * m_impl;
};
Group * g1 = new ConcreteGroup<A>;
Group * g1 = new ConcreteGroup<B>;
You could make Group< Base > a base class of all Group< T > T != Base.
class Base {
public:
virtual ~Base() { };
};
class Derived : public Base { };
template <typename T> class Group;
struct Empty { };
template <typename T>
struct base_for_group_t {
typedef Group<Base> type;
};
template <>
struct base_for_group_t<Base> {
typedef Empty type;
};
template <typename T>
class Group : public base_for_group_t<T>::type { };
int main() {
Group<Base> *g = 0;
g = new Group<Base>(); // Works
g = new Group<Derived>(); // now works
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With