错误:无法将“ std :: basic_ostream< char>”左值绑定到“ std :: basic_ostream< char>&&” [英] error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’

查看:279
本文介绍了错误:无法将“ std :: basic_ostream< char>”左值绑定到“ std :: basic_ostream< char>&&”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过几个问题,特别是重载运算符<< ;:不能将左值绑定到'std :: basic_ostream< char>&'
非常有用。它让我知道我的问题是我在做c ++ 11无法推断出类型的事情。

I have already looked at a couple questions on this, specifically Overloading operator<<: cannot bind lvalue to ‘std::basic_ostream<char>&&’ was very helpful. It let me know that my problem is I'm doing something that c++11 can't deduce the type from.

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

I think a big part of my problem is that the instantiated class I'm working with, is templated, but originally obtained from a pointer to a non-template base class. This is something I did advised from another stackoverflow.com question about how to put template class objects into an STL container.

我的类:

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

并且,代码段的编译错误 database.cc:530:90:错误:无法将'std :: basic_ostream< char>'左值绑定到'std :: basic_ostream< char>&&'发生:

And, the code snippet where the compile error database.cc:530:90: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’ occurs:

//nb:  typedef std::map<std::string,DbValueBase*>  DbValueMap;
    const CommPoint::DbValueMap&    db_values = cp.value_map();
    for (auto i = db_values.cbegin() ; i != db_values.cend() ; i++) {
        // TODO: Need to implement an ostream operator, and conversion
        // operators, for DbValueBase and DbValue<>
        // TODO: Figure out how to get a templated output operator to
        // work... 
 //     DbValue<std::string> *k = dynamic_cast<DbValue<std::string>*>(i->second);
        std::cerr << "  Database field " << i->first << " should have value " << *(i->second) << endl;
    }

如果我的输出尝试打印 i->,第二,它会编译并运行,我看到了指针。如果我尝试输出 *(i-> second),则会收到编译错误。当单步执行gdb时,似乎仍然知道 i->秒的类型正确

If my output tries to print i->second, it compiles and runs, and I see the pointer. If I try to output *(i->second), I get the compile error. When single-stepping in gdb, it seems to still know that i->second is of the correct type

(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

我希望自己做错了什么。但是,它比我自己能够解决的复杂得多。其他人看到我做错了或不完整的事情是什么?

I'm hoping that I'm doing something subtly wrong. But, it's more complicated than I seem to be able to figure it out on my own. Anyone else see what thing(s) I've done wrong or incompletely?

编辑:

@PiotrNycz确实为我下面提出的问题提供了很好的解决方案。但是,尽管当前在进行开发时会打印值,但对于这些 DbValue<> 对象的真正需求是使它们返回正确类型的值,然后我可以将其输入数据库操作方法。我应该在最初的问题中提到打印是有价值的,但不是目标的终点。

@PiotrNycz did give a good solution for my proposed problem below. However, despite currently printing values while doing development, the real need for these DbValue<> objects is to have them return a value of the correct type which I can then feed to database operation methods. I should've mentioned that in my original question, that printing is of value, but not the end of my goal.

推荐答案

尽管调试器正确地将 *(i-> second)标识为 DbValue< std :: string> ,则使用仅在运行时可用的信息进行确定。

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.

编译器只知道它与 DbValueBase& 一起使用。

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.

用于获取 DbValueBase& > DbValue<> 对象,您可能想循环进入访客设计模式。

For obtaining the contents of a DbValue<> object through a DbValueBase&, you might want to loop into the Visitor design pattern.

一些示例代码:

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

这篇关于错误:无法将“ std :: basic_ostream&lt; char&gt;”左值绑定到“ std :: basic_ostream&lt; char&gt;&amp;&amp;”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆