kaelumania
kaelumania

Reputation: 51

C++ Template Specialization with Inheritance

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

Answers (2)

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

riv
riv

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

Related Questions