C ++派生类是模板化的,基础不是:如何从基类获取类型?

时间:2015-11-20 20:59:52

标签: c++ templates inheritance casting

我正在使用第三方专有软件包。它使用如下所示的数据模型:

class Base {
    ...
}

template<class T>
class Derived: public Base {
protected:
  T _t;
public:
T& getData();
}

当我与他们的代码交互时,他们将指针交给Base个对象。我想写一些自己的模板化函数。我怎样才能做到这一点?即如果我知道T型,我可以施展它,但如果我不知道它的类型怎么办?我想要的是一个看起来像这样的函数:

template<T>
DataToString(Derived<T> d){
    std::stringstream ss;
    ss << d.getData();
    return ss.str();
}

可称为:     基地b;     std :: cout&lt;&lt; DataToString(B);

但是当我尝试时,编译器告诉我它不能匹配模板。我现在得到的是“猜测并检查”if / else是否阻止每种数据类型,我想知道是否有更好的方法。

我认为我的问题与this有关,但就我而言,我正在使用第三方库。

1 个答案:

答案 0 :(得分:0)

这个怎么样:

class Base {
    ...
};

class IntermediateBase : public Base {
public:
    virtual std::string toString() const = 0;
};

template<typename T>
class Derived : public IntermediateBase {
    std::string toString() const override { return "blah blah"; }
};

所以基本上你创建一个包含虚拟toString函数的中间基类。你知道每个Base*都属于那种类型,因为你的所有类型都是从它派生的,所以你可以转换它并调用虚函数。

Base* basePtr = ...;
IntermediateBase* intermediateBasePtr = static_cast<IntermediateBase*>(basePtr);
std::string s = intermediateBasePtr->toString();

你也可以把你的功能写成......

std::string DataToString(Base* p) {
    return static_cast<IntermediateBase*>(p)->toString();
}

如果不是每个来自Base的类型都是你的,你可以dynamic_cast检查它是否是IntermediateBase(我强烈建议你做出更好的类名:))