模板参数的继承层次结构

时间:2017-05-17 11:22:41

标签: c++ templates inheritance

我需要创建一个类型擦除模式,它允许检索从给定基类继承的所有包含的对象。据我所知,像boost :: any这样的流行类型擦除只有在请求和包含的类完全匹配时才允许使用any_cast检索对象,因此它不符合我的需要。

我可以用模板类解决​​问题,模板类模仿模板参数的继承关系。例如,TemplateClass<Derived>应为TemplateClass<Base>的子项,以便以下示例有效:

// 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;
    }
  }
}

是否有实现此行为的模式?或最终另一种解决方案 感谢。

2 个答案:

答案 0 :(得分:1)

你无法完全按照自己的意愿行事,但你可以通过模板和操作员获得更接近的东西 作为一个最小的工作示例:

#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;
}

如果您将评论切换到最后一行,则A不会再编译,而B不是{{1}}的基础。

答案 1 :(得分:0)

我不知道你是否正在寻找它,但你可以这样做:

template <typename T>
class Derived : public T
{

};

然后使用名为Base的母类来实例化它:

Derived<Base> object;

您最终会从Base

获得此信息
class Derived : public Base
{

};