C++ 模板参数的继承层次结构
我需要创建一个类型擦除模式,该模式允许检索从给定基类继承的所有包含的对象。据我所知,像boost::any这样的流行类型擦除只允许在请求的类和包含的类完全匹配的情况下检索具有任何类型转换的对象,因此它不适合我的需要 我可以用template类来解决这个问题,它模仿了template参数的继承关系。例如,C++ 模板参数的继承层次结构,c++,templates,inheritance,C++,Templates,Inheritance,我需要创建一个类型擦除模式,该模式允许检索从给定基类继承的所有包含的对象。据我所知,像boost::any这样的流行类型擦除只允许在请求的类和包含的类完全匹配的情况下检索具有任何类型转换的对象,因此它不适合我的需要 我可以用template类来解决这个问题,它模仿了template参数的继承关系。例如,TemplateClass应该是TemplateClass的子级,这样下面的示例就可以工作了: // Suppose all clases have virtual destructors so
TemplateClass
应该是TemplateClass
的子级,这样下面的示例就可以工作了:
// Suppose all clases have virtual destructors so that vtable and RTTI info are available
class ObjectWrapperBase {
}
template<class DataType>
class ObjectWrapperT: public ObjectWrapperBase {
public:
ObjectWrapperBase(T* ptr): dataObjPtr(ptr){}
DataType *dataObjPtr;
}
class Base{}
class Derived: public Base{}
class NotDerivedFromBase{}
int main(){
std::vector<ObjectWrapperBase*> v;
v.push_back(new ObjectWrapperT<Base>(new Base));
v.push_back(new ObjectWrapperT<Derived>(new Derived));
v.push_back(new ObjectWrapperT<NotDerivedFromBase>(new NotDerivedFromBase));
// Now suppose I want to retrieve all the Base and children objects in v
// If ObjectWrapperT<Derived> is a child of ObjectWrapperT<Base> I can write:
for(int i = 0; i < v.size(); i++){
ObjectWrapperT<Base> *wPtr = dynamic_cast<ObjectWrapperT<Base>*>(v[i]);
if(wPtr){
Base *basePtr = wPtr->dataObjPtr;
}
}
}
//假设所有类都有虚拟析构函数,以便vtable和RTTI信息可用
类ObjectWrapperBase{
}
模板
类ObjectWrapperT:PublicObjectWrapperBase{
公众:
ObjectWrapperBase(T*ptr):dataObjPtr(ptr){}
数据类型*dataObjPtr;
}
类基{}
派生类:公共基{}
类NotDerivedFromBase{}
int main(){
std::向量v;
v、 向后推(新ObjectWrapperT(新基));
v、 向后推(新对象包装器(新派生));
v、 向后推(新对象包装器(新NotDerivedFromBase));
//现在假设我想要检索v中的所有基对象和子对象
//如果ObjectWrapperT是ObjectWrapperT的子级,我可以写:
对于(int i=0;idataObjPtr;
}
}
}
有没有一种模式可以实现这种行为?还是最终另一种解决方案?
谢谢。我不知道这是否是您想要的,但您可以这样做:
template <typename T>
class Derived : public T
{
};
Derived<Base> object;
您最终将从Base
获得此信息:
class Derived : public Base
{
};
您不能完全按照自己的意愿去做,但您可以通过模板和操作符更进一步。
作为一个最低限度的工作示例:
#include<type_traits>
template<typename D>
struct S {
S(D *d): d{d} {}
template<typename B, typename = std::enable_if_t<std::is_base_of<B, D>::value>>
operator S<B>() {
return {d};
}
private:
D *d;
};
struct B {};
struct D: B {};
struct A {};
int main() {
S<D> sd{new D};
S<B> sb = sd;
// S<A> sa = sd;
}
#包括
模板
结构{
S(D*D):D{D}{
模板
运算符S(){
返回{d};
}
私人:
D*D;
};
结构B{};
结构D:B{};
结构A{};
int main(){
S sd{new D};
S sb=标准差;
//S sa=标准差;
}
如果将注释切换到最后一行,它将不再编译,因为
A
不是B
的基础 我不确定我是否正确理解了你的问题,如果我错了,请纠正我-你的派生类
和基类
是独立于你创建的模板类
,你不知道它们在模板类
中的继承结构。如果这样,我认为你不能实现你想要的,因为C++类型的特性不实现接口来获得类的直接父类。是的,派生和基与TabPraceLASS没有关系,TimePcLASS对它们一无所知。我也在说服自己,没有办法在C++中得到我想要的东西……如果你让<代码> TemplateClass <代码>的用户决定你的代码< >派生< <代码> >代码> BASE>代码>关系,比如通过提供代码< TemplateClass >代码>的自定义特性,让用户共享,你可以找到一个解决办法。带有模板类的继承结构。但老实说,我不确定这是否是你真正想要的。谢谢,这是有效的,但不是我想要实现的。事实上,我可能把情况简单化了。实际上,我的TemplateClass是一个类型擦除模式中的占位符,它包含模板参数类的一个对象实例。TemplateClass是另一个非模板类的子类,称之为ClassBase,在运行时,我有一个指向ClassBase的指针,它指向一个TemplateClass对象,该对象属于具有未知模板参数的TemplateClass的专门化。因此,在编译时,实际的类型是未知的,因此我认为没有任何模板元编程技术可以提供帮助。好吧,我可以尝试找出一种有效的方法,但您应该在问题中提供一个或多或少类似于实际情况的最小示例。否则就不可能说它是否存在解决方案。我添加了一个示例,并解释了我面临的实际问题。谢谢你的关注,skypjack