我遇到了来自同一模板类的不同实例的多重继承问题。具体来说,我正在尝试这样做:
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&lt;什么&gt;和基地&lt; SomethingElse&gt;,我可以通过消除对createBase的调用来解决它:
Something* smth1 = d->Base<Something>::createBase<Something>();
SomethingElse* smth2 = d->Base<SomethingElse>::createBase<SomethingElse>();
然而,这种解决方案在语法上讲是非常不切实际的,而且我更喜欢更优雅的东西。而且,我对第一条错误信息感到困惑。它似乎意味着有一个实例化createBase&lt; SomethingElse&gt;在Base&lt;有点&gt;但是怎么可能呢?有关此问题的任何信息或建议将不胜感激。
答案 0 :(得分:2)
似乎暗示
createBase< SomethingElse >
中有一个实例化Base< Something >
,但这怎么可能呢?
肯定有,因为您的createBase<T>()
是成员模板函数(此函数中的T
与周围类中的T
无关。)
我会做类似的事情:
// in Derived, or you could make some class (eg. MultiBase) for it
template <class T>
T* createBase()
{
return Base<T>::createBase();
}
答案 1 :(得分:0)
这两个函数的“全名”是这样的:
template<class T> T* Derived::Base<Something>::createBase<T>();
据我所知,您的createBase()
函数是模板化类中的模板化函数。从我所看到的,你想要在它前面删除`template``。
但是,这不应该完全解决您的问题,因为Derived
会(仍然)同时拥有Base<Something>::createBase()
和Base<SomethingElse>::createBase()
。
jpalecek的答案将为您完成解决问题,或者您可以访问该对象,就好像它是一个特定的基础:
Base<Something> * pBase = new Derived();
pBase->createBase();
或
static_cast<Base<Something> >(d)->createBase();
或者,添加到jpalecek的答案,
static_cast<Base<T> >(this)->createBase();
应该工作,我认为是类型安全的;也就是说,如果this
未从Base<T>