15
4

2 回答 2

4

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();
    }
};
于 2012-11-12T16:53:58.430 回答
3

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;
};
于 2012-11-13T16:04:03.813 回答