简体   繁体   English

错误:无法绑定&#39;std :: basic_ostream <char> &#39;左右&#39;std :: basic_ostream <char> &amp;&amp;”

[英]error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’

I have already looked at a couple questions on this, specifically Overloading operator<<: cannot bind lvalue to 'std::basic_ostream<char>&&' was very helpful. 我已经看过几个关于这个的问题,特别是重载运算符<<:无法将左值绑定到'std :: basic_ostream <char> &&'非常有帮助。 It let me know that my problem is I'm doing something that c++11 can't deduce the type from. 它让我知道我的问题是我正在做一些c ++ 11无法从中推断出类型的东西。

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. 这是我从另一个stackoverflow.com问题中建议的关于如何将模板类对象放入STL容器的问题。

My classes: 我的课程:

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

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: 并且,编译错误database.cc:530:90: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'的代码片段出现:

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

If my output tries to print i->second , it compiles and runs, and I see the pointer. 如果我的输出尝试打印i->second ,它会编译并运行,我会看到指针。 If I try to output *(i->second) , I get the compile error. 如果我尝试输出*(i->second) ,我会收到编译错误。 When single-stepping in gdb, it seems to still know that i->second is of the correct type 当单步执行gdb时,它似乎仍然知道i->second的类型正确

(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? 其他人看到我做错了什么或不完整的事情?

Edit: 编辑:

@PiotrNycz did give a good solution for my proposed problem below. @PiotrNycz确实为我提出的问题提供了一个很好的解决方案。 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. 但是,尽管在进行开发时当前打印值,但对这些DbValue<>对象的真正需求是让它们返回正确类型的值,然后我可以将其提供给数据库操作方法。 I should've mentioned that in my original question, that printing is of value, but not the end of my goal. 我应该提到,在我原来的问题中,印刷是有价值的,但不是我的目标的终点。

If you want to print object by base pointer - make the ostream operator in base class: 如果要通过基指针打印对象 - 在基类中创建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();
    }
};

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. 虽然调试器正确地将*(i->second)标识为DbValue<std::string> ,但是使用仅在运行时可用的信息进行该确定。

The compiler only knows that it is working with a DbValueBase& and has to generate its code on that basis. 编译器只知道它正在使用DbValueBase&并且必须在此基础上生成其代码。 Therefore, it can't use the operator<<(std::ostream&, const DbValue<T>&) as that does not accept a DbValueBase or subclass. 因此,它不能使用operator<<(std::ostream&, const DbValue<T>&) ,因为它不接受DbValueBase或子类。


For obtaining the contents of a DbValue<> object through a DbValueBase& , you might want to loop into the Visitor design pattern. 要通过DbValueBase&获取DbValue<>对象的内容,您可能希望循环访问者设计模式。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法绑定&#39;std :: ostream {aka std :: basic_ostream <char> }&#39;左值成&#39;std :: basic_ostream <char> &amp;&amp;” - cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' 错误:无法绑定&#39;std :: ostream {aka std :: basic_ostream <char> }&#39;左值成&#39;std :: basic_ostream <char> &amp;&amp;&#39; - error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’ 错误:无法绑定 'std::ostream {aka std::basic_ostream<char> }'左值为'std::basic_ostream<char> &&'</char></char> - error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' 重载运算符&lt;&lt;:无法绑定&#39;std :: basic_ostream <char> &#39;左值到&#39;std :: basic_ostream <char> &amp;&amp;&#39; - Overloading operator<<: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’ std :: vector:无法绑定&#39;std :: ostream {aka std :: basic_ostream <char> &#39;&#39;左右&#39;到&#39;std :: basic_ostream <char> &amp;&amp;” - std::vector : cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' 重载operator <<:无法将左值绑定到'std :: basic_ostream <char> &&' - Overloading operator<<: cannot bind lvalue to ‘std::basic_ostream<char>&&’ high_resolution_clock错误:无法绑定&#39;std :: ostream {aka std :: basic_ostream <char> }&#39;左值成&#39;std :: basic_ostream <char> &amp;&amp;&#39; - high_resolution_clock error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’ 错误:无法绑定&#39;std :: ostream {aka std :: basic_ostream <char> } - Error: cannot bind 'std::ostream {aka std::basic_ostream<char>} boost :: PO并且不能绑定到&#39;std :: basic_ostream <char> &amp;&amp;” - boost::PO and cannot bind to ‘std::basic_ostream<char>&&’ 错误:无法将 'std::basic_ostream' 左值绑定到 'std::basic_ostream&amp;&amp;' sl &lt;&lt; ss; - error: cannot bind ‘std::basic_ostream’ lvalue to ‘std::basic_ostream&&’ sl << ss;
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM