模板类的多重继承
我遇到来自同一模板类的不同实例的多重继承问题。具体来说,我正在尝试执行此操作:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
肯定有,因为你的 createBase() 是一个成员模板函数(并且此函数中的
T
与T
无关) code> 在周围的类中)。我会做类似的事情:
There surely is, because your
createBase<T>()
is a member template function (and theT
in this function has nothing to do with theT
in the surrounding class).I'd do something like:
这两个函数的“全名”是这样的:
据我所知,您的 createBase() 函数是模板化类中的模板化函数。据我所知,你想把“模板”放在它前面。
但是,这不应该完全解决您的问题,因为
Derived
仍然会同时具有Base::createBase()
和Base;::createBase()
。jpalecek 的答案将为您解决问题,或者您可以访问该对象,就好像它是特定的基础一样:
或者
或者,添加到 jpalecek 的答案中,
应该有效,并且我认为是类型安全的;也就是说,如果
this
不是从Base
继承,则不起作用The "full names" of both functions is something like this:
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 bothBase<Something>::createBase()
andBase<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:
or
Or, to add to jpalecek's answer,
Should work, and I think be type-safe; that is, won't work if
this
isn't inheriting fromBase<T>