模板类的多重继承

发布于 2024-09-02 11:52:11 字数 1875 浏览 0 评论 0原文

我遇到来自同一模板类的不同实例的多重继承问题。具体来说,我正在尝试执行此操作:

template <class T>
class Base
{

public:

    Base() : obj(NULL)
    {
    }

    virtual ~Base()
    {
        if( obj != NULL ) delete obj;
    }

    template <class T>
    T* createBase()
    {
        obj = new T();

        return obj;
    }

protected:

    T* obj;

};

class Something
{
    // ...
};

class SomethingElse
{
    // ...
};

class Derived : public Base<Something>, public Base<SomethingElse>
{

};

int main()
{
    Derived* d = new Derived();
    Something* smth1 = d->createBase<Something>();
    SomethingElse* smth2 = d->createBase<SomethingElse>();

    delete d;

    return 0;
}

当我尝试编译上述代码时,出现以下错误:

1>[...](41) : error C2440: '=' : cannot convert from 'SomethingElse *' to 'Something *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>        [...](71) : see reference to function template instantiation 'T *Base<Something>::createBase<SomethingElse>(void)' being compiled
1>        with
1>        [
1>            T=SomethingElse
1>        ]
1>[...](43) : error C2440: 'return' : cannot convert from 'Something *' to 'SomethingElse *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

由于成员 obj 是从 Base<< 继承的,所以问题似乎不明确。某事>且基数< SomethingElse >,我可以通过消除对 createBase 的调用的歧义来解决它:

Something* smth1 = d->Base<Something>::createBase<Something>();
SomethingElse* smth2 = d->Base<SomethingElse>::createBase<SomethingElse>();

但是,从语法上讲,这个解决方案非常不切实际,而且我更喜欢更优雅的东西。此外,我对第一条错误消息感到困惑。似乎暗示有一个实例化createBase<其他>在基地<某事>,但这怎么可能呢?任何有关此问题的信息或建议将不胜感激。

I'm having issues with multiple inheritance from different instantiations of the same template class. Specifically, I'm trying to do this:

template <class T>
class Base
{

public:

    Base() : obj(NULL)
    {
    }

    virtual ~Base()
    {
        if( obj != NULL ) delete obj;
    }

    template <class T>
    T* createBase()
    {
        obj = new T();

        return obj;
    }

protected:

    T* obj;

};

class Something
{
    // ...
};

class SomethingElse
{
    // ...
};

class Derived : public Base<Something>, public Base<SomethingElse>
{

};

int main()
{
    Derived* d = new Derived();
    Something* smth1 = d->createBase<Something>();
    SomethingElse* smth2 = d->createBase<SomethingElse>();

    delete d;

    return 0;
}

When I try to compile the above code, I get the following errors:

1>[...](41) : error C2440: '=' : cannot convert from 'SomethingElse *' to 'Something *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>        [...](71) : see reference to function template instantiation 'T *Base<Something>::createBase<SomethingElse>(void)' being compiled
1>        with
1>        [
1>            T=SomethingElse
1>        ]
1>[...](43) : error C2440: 'return' : cannot convert from 'Something *' to 'SomethingElse *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

The issue seems to be ambiguity due to member obj being inherited from both Base< Something > and Base< SomethingElse >, and I can work around it by disambiguating my calls to createBase:

Something* smth1 = d->Base<Something>::createBase<Something>();
SomethingElse* smth2 = d->Base<SomethingElse>::createBase<SomethingElse>();

However, this solution is dreadfully impractical, syntactically speaking, and I'd prefer something more elegant. Moreover, I'm puzzled by the first error message. It seems to imply that there is an instantiation createBase< SomethingElse > in Base< Something >, but how is that even possible? Any information or advice regarding this issue would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情定在深秋 2024-09-09 11:52:11

似乎暗示有一个实例化createBase< Base< 中的 SomethingElse >有些东西>,但这怎么可能呢?

肯定有,因为你的 createBase() 是一个成员模板函数(并且此函数中的 TT 无关) code> 在周围的类中)。

我会做类似的事情:

// in Derived, or you could make some class (eg. MultiBase) for it

template <class T>
T* createBase()
{
  return Base<T>::createBase();
}

It seems to imply that there is an instantiation createBase< SomethingElse > in Base< Something >, but how is that even possible?

There surely is, because your createBase<T>() is a member template function (and the T in this function has nothing to do with the T in the surrounding class).

I'd do something like:

// in Derived, or you could make some class (eg. MultiBase) for it

template <class T>
T* createBase()
{
  return Base<T>::createBase();
}
樱花细雨 2024-09-09 11:52:11

这两个函数的“全名”是这样的:

template<class T> T* Derived::Base<Something>::createBase<T>();

据我所知,您的 createBase() 函数是模板化类中的模板化函数。据我所知,你想把“模板”放在它前面。

但是,这不应该完全解决您的问题,因为 Derived 仍然会同时具有 Base::createBase()Base;::createBase()

jpalecek 的答案将为您解决问题,或者您可以访问该对象,就好像它是特定的基础一样:

Base<Something> * pBase = new Derived();
pBase->createBase();

或者

static_cast<Base<Something> >(d)->createBase();

或者,添加到 jpalecek 的答案中,

static_cast<Base<T> >(this)->createBase(); 

应该有效,并且我认为是类型安全的;也就是说,如果 this 不是从 Base 继承,则不起作用

The "full names" of both functions is something like this:

template<class T> T* Derived::Base<Something>::createBase<T>();

From what I know, your createBase() function is a templated function within a templated class. From what I can see, you want to drop the `template`` in front of it.

However, that shouldn't completely solve your problem, because Derived would then (still) have both Base<Something>::createBase() and Base<SomethingElse>::createBase().

jpalecek's answer would finish solving the problem for you, or you can access the object as if it were a particular base:

Base<Something> * pBase = new Derived();
pBase->createBase();

or

static_cast<Base<Something> >(d)->createBase();

Or, to add to jpalecek's answer,

static_cast<Base<T> >(this)->createBase(); 

Should work, and I think be type-safe; that is, won't work if this isn't inheriting from Base<T>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文