Reputation: 51
Following Situation:
class FeatureBase
class Feature1 : public FeatureBase
class FeatureAttrBase
class Feature1Attr : public FeatureAttrbase
FeatureBase contains a list of FeatureAttrBase and should be able to create and manage these objects. Therefore i use a template on FeatureBase.
template<class T = FeatureAttrBase> class FeatureBase
creating and managing the attributes (e.g. new T())
and the subclasses use a specialized inheritance
class Feature1 : public FeatureBase<Feature1Attr>
Anywhere else in my code i wrote a method
RegisterFeature(FeatureBase<FeatureAttrBase>* feature)
but the compiler gives me an error that it was unable to convert between Feature1 and FeatureBase. In the mentioned method i only need to use information from FeatureAttrBase. But inside Feature1 i need access to Feature1Attr.
Thus the question is how to solve this issue? Do i have to change my datastructure?
Upvotes: 1
Views: 3591
Reputation: 171127
You could inherit the specialisations of FeatureBase
from FeatureBase<FeatureAttrBase>
. Something like this:
// Forward declaration
template <typename T>
class FeatureBase;
// Type selecting trait class FeatureBase_BaseClass
// FeatureBase for derived Attrs will inherit from FeatureBase<FeatureAttrBase>
template <typename T>
struct FeatureBase_BaseClass
{
typedef FeatureBase<FeatureAttrBase> Type;
};
// FeatureBase<FeatureAttrBase> will inherit from a dummy type
template <>
struct FeatureBase_BaseClass<FeatureAttrBase>
{
struct Type {};
};
// Use FeatureBase_BaseClass to select the proper base class for FeatureBase
template <typename T = FeatureAttrBase>
class FeatureBase : public FeatureBase_BaseClass<T>::Type
{
//as before
};
This way, all FeatureBase<X>
for specific attributes X
will inherit from FeatureBase<FeatureAttrBase>
.
Upvotes: 0
Reputation: 7323
Having template parameters inherit from each other doesn't make template classes related. You should instead do something like the following (might not be the best solution but you haven't specified what you are trying to do):
class FeatureAttrBase;
class FeatureBase
{
public:
virtual FeatureAttrBase* GetAttributes() = 0;
};
template<class T>
class FeatureImpl : public FeatureBase
{
T attr;
public:
FeatureAttrBase* GetAttributes()
{
return &attr;
}
};
class Feature1Attr : public FeatureAttrBase;
class Feature1 : public FeatureImpl<Feature1Attr>;
In fact, you probably don't need the FeatureImpl
class and can put the implementation directly in the Feature1
class (and get rid of templates completely).
Upvotes: 1