2 回答
If you want to print object by base pointer - make the ostream operator in base class:
class DbValueBase {
protected:
virtual ~DbValueBase() {}
virtual void print(std::ostream&) const = 0;
friend std::ostream& operator << (std::ostream& os, const DbValueBase & obj)
{
obj.print(os); return os;
}
};
template <typename T>
class DbValue : public DbValueBase {
public:
void print(std::ostream& os) const
{
out << dataref();
}
};
Although the debugger correctly identifies *(i->second)
as being of the type DbValue<std::string>
, that determination is made using information that is only available at runtime.
The compiler only knows that it is working with a DbValueBase&
and has to generate its code on that basis. Therefore, it can't use the operator<<(std::ostream&, const DbValue<T>&)
as that does not accept a DbValueBase
or subclass.
For obtaining the contents of a DbValue<>
object through a DbValueBase&
, you might want to loop into the Visitor design pattern.
Some example code:
class Visitor {
public:
template <typename T>
void useValue(const T& value);
};
class DbValueBase {
public:
virtual void visit(Visitor&) = 0;
};
template <class T>
class DbValue : public DbValueBase {
pblic:
void visit(Visitor& v) {
v.useValue(m_val);
}
private:
T m_val;
};