error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
c++, templates
Solution
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;
};
Problem
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. 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. 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: ``` //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. 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? Edit: @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.