C++ 错误:无法绑定‘;std::basic_ostream<;char>’;左值为‘;std::basic_ostream<;char>&&’;

C++ 错误:无法绑定‘;std::basic_ostream<;char>’;左值为‘;std::basic_ostream<;char>&&’;,c++,templates,C++,Templates,我已经看了一些关于这方面的问题,特别是 非常有帮助。它让我知道我的问题是我正在做一些c++11无法从中推断类型的事情 我认为我的问题很大一部分是我正在使用的实例化类是模板化的,但最初是从指向非模板基类的指针获得的。这是我在stackoverflow.com的另一个问题中提出的关于如何将模板类对象放入STL容器的建议 我的班级: class DbValueBase { protected: virtual void *null() { return NULL; } // Neede

我已经看了一些关于这方面的问题,特别是 非常有帮助。它让我知道我的问题是我正在做一些c++11无法从中推断类型的事情

我认为我的问题很大一部分是我正在使用的实例化类是模板化的,但最初是从指向非模板基类的指针获得的。这是我在stackoverflow.com的另一个问题中提出的关于如何将模板类对象放入STL容器的建议

我的班级:

class DbValueBase {
  protected:
    virtual void *null() { return NULL; }   // Needed to make class polymorphic
};

template <typename T>
class DbValue : public DbValueBase {
  public:
    DbValue(const T&val)  { data = new T(val); }
    ~DbValue() { if (data) delete data; }

    T   *data;

    const T&    dataref() const { return *data; } 

    friend std::ostream& operator<<(std::ostream& out, const DbValue<T>& val)
    {
        out << val.dataref();
        return out;
    }
}
我希望我在做一些微妙的错误。但是,这比我自己能弄明白的要复杂得多。还有人知道我做错了什么或做得不彻底吗

编辑:


@PiotrNycz确实为我下面提出的问题提供了一个很好的解决方案。然而,尽管目前正在进行开发时打印值,但这些
DbValue
对象的真正需要是让它们返回正确类型的值,然后我可以将该值提供给数据库操作方法。我应该在我的原始问题中提到,打印是有价值的,但不是我的目标的终点。

如果要按基指针打印对象,请在基类中使用ostream操作符:

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();
    }
};
classdbvaluebase{
受保护的:
虚拟~DbValueBase(){}
虚拟空打印(std::ostream&)常量=0;

friend std::ostream&operator尽管调试器正确地将
*(i->second)
标识为类型
DbValue
,但该确定是使用仅在运行时可用的信息进行的


编译器只知道它使用的是
DbValueBase&
,并且必须在此基础上生成代码。因此,它不能使用
运算符
virtual void*null(){return null;}//需要使类具有多态性
相反,您只需将析构函数声明为虚拟,您无论如何都需要这样做。
virtual~DbValueBase()=default;
@barnes53谢谢。这意味着我必须添加一个
noexcept(true)
对于模板子类析构函数,我确信这与
默认值有关,但比未使用的方法更干净。谢谢。谢谢。很抱歉,我不知道如何让编译器找出DbValue::Operator的正确形式。然而,我意识到我只是在谈论打印,因为这就是我正在做的到目前为止。但是,我还需要将这些对象转换为模板类型,因为我需要将它们插入数据库。您的解决方案将用于执行操作,但不用于返回值。也许我应该扩展我原来的问题来说明这一点。@cross这是一种通用方法。请尝试以下方法:
virtual void DbValueBase::insertMe(数据库和数据库)=0;
我必须看看这是否适合我的需要。我想,我想有效地返回值,但这似乎不适合。我需要看看是否可以编写一个访问者函数来应用这些值。当我更接近使用数据值对象时,我会有一个更好的主意。感谢指针/sug在我的情况下,如何使用访问者设计模式来应用这些值(
typename T
)有点复杂作为对象的参数,但能够做到。在构建过程中,只需将对象构建到访问者中,然后就可以像上面的示例一样使用它。这是现在公认的答案。再次感谢!
(gdb) p i->second
$2 = (DbValueBase *) 0x680900
(gdb) p *(i->second)
warning: RTTI symbol not found for class 'DbValue<std::string>'
$3 = warning: RTTI symbol not found for class 'DbValue<std::string>'
{_vptr.DbValueBase = 0x4377e0 <vtable for DbValue<std::string>+16>}
(gdb) quit
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();
    }
};
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;
};