0

I'm using a 3rd party proprietary software package. It uses a data model that looks like this:

class Base {
    ...
}

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

When I interact with their code, they hand me pointers to Base objects. I'd like to write some templated functions of my own. How can I do this? i.e. if I knew the type T, I could cast it, but what if I don't know the type? What I'd like is a function looking something like this:

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

which may be called: Base b; std::cout << DataToString(b);

but when I try that, the compiler tells me it can't match the templates. What I've got right now is a "guess and check" if/else block for each data type and I"m wondering if there's a better way.

I think my question sort of related to this, but in my case I'm using a 3rd party library.

amos
  • 5,092
  • 4
  • 34
  • 43
  • The type `T` is *part* of the derived class type, so there's no way to access the derived class without knowing that template type. You need to implement `DataToString` as part of the derived type and make it polymorphic. – Mark Ransom Nov 20 '15 at 21:04

1 Answers1

0

How about this:

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

So basically you make an intermediate base class which contains a virtual toString function. You know every Base* will be of that type because all of your types derive from it, so you can cast to that and call the virtual function.

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

You could also write your function as....

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

And if not every type derived from Base is yours, you could dynamic_cast to check if it is a IntermediateBase (I highly recommend you make better class names :))

David
  • 27,652
  • 18
  • 89
  • 138