Overloading Operator<<: Cannot Bind Lvalue to 'Std::Basic_Ostream<Char>&&'

Overloading operator : cannot bind ‘std::basic_ostream char ’ lvalue to ‘std::basic_ostream char &&’

FIRST PROBLEM:

To make your program compile, just use an lvalue reference to const as the second parameter of your operator << (both in the friend-declaration and in the definition of that function):

template < class U, unsigned int M >
std::ostream& operator<< ( std::ostream &out, Vector< U, M > const& cVector )
// ^^^^^

The reason why your program won't compile is that your overload of operator << accepts an lvalue reference to non-const as its second argument, and lvalue references to non-const cannot bind to rvalues.

Since the result of operator + between two instances of Vector is a temporary, and a temporary is an rvalue, the compiler can't invoke your operator <<, and is therefore unable to resolve the call.

SECOND PROBLEM:

Once you fixed the above issue, you'll have to solve a second one: your Vector class template does not provide a const version of operator [], so your rewritten operator <<, which now accepts a reference to a const vector, won't be able to access the vector's elements.

template < class T, unsigned int N >
class Vector
{
// ...

T& operator[] ( const unsigned int& );

T const& operator[] ( const unsigned int& ) const; // <== ADD THIS!

// ...
};

And of course the corresponding definition:

template < class T, unsigned int N >
T const& Vector< T, N >::operator[] ( const unsigned int &index ) const
{
return _values[ index ];
}

Overloading operator : cannot bind lvalue to ‘std::basic_ostream char &&’

Bo provided the reason why this is happening (the type T is not deducible in the call to the nested operator<<. A simple workaround for this, and something that I recommend in general, not only here, is not befriending a template, but rather a single free function. For that you will need to define the function inline:

template<typename T>
struct classA {
struct classB
{
friend inline std::ostream& operator<< (std::ostream &out,
const classB &b) {
// definition goes here
}
};

classB root;

friend std::ostream& operator<< (std::ostream &out,
const classA<U> &tree) {
// definition goes here
}
};

There are a couple of differences among the two approaches. The most important one is that this approach will have the compiler define a non-templated overload for operator<< for each instantiation of the template, which because it is no longer a template, does not depend on deducing the arguments. Another side effects are that the approach is a little tighter (you are only befriending one function, while in your initial approach you befriended the template and all possible instantiations (which can be used as a loophole to gain access to your class internals). Finally the functions so defined will only be found through ADL, so there are less overloads of operator<< for the compiler to consider when the argument is not ClassA<T> or ClassA<T>::ClassB.


How access can be gained with your approach

namespace {
struct intruder {
ClassA & ref;
intruder( ClassA& r ) : ref(r) {}
};
template <>
std::ostream& operator<< <intruder>( std::ostream& _, ClassA<intruder> const& i ) {
std::cout << i.ref.private_member << std::endl;
return _;
}
}

Alternative

Alternatively you can befriend a particular specialization of a template. That will solve the intruder problem, as it will only be open to operator<< to ClassA<intruder>, which has a much lesser impact. But this will not solve your particular issue, as the type would still not be deducible.

no match and cannot bind lvalue errors while overloading `operator ` with `std::wostream` and `std::string`

This is a bad idea:

inline std::wostream &operator<<(std::wostream &os, const std::string &)

as you should not overload operators on two types in std that do not depend on your own (outside of std or build-in) types. Doing ... doesn't work well. And, in my opinion, shouldn't be allowed.

Regardless, you can generate the same problem with conforming code by simply creating your own namespace notstd and own type notstd::string, then in the global root namespace defining

inline std::wostream &operator<<(std::wostream &os, const notstd::string &)
{
return os;
}

and get the same symptoms. So that doesn't matter much.


Operators are found first via unqualified name lookup, then via argument dependent lookup.

As we have no using statement, unqualified name lookup first looks in the enclosing namespace. If nothing is found, the namespaces containing it (and eventually the file/global namespace) are then searched.

ADL then augments this with operators found via ADL or Koenig lookup -- it looks in the namespaces of the arguments and their template parameters.

Now, the friend operator<< you defined do live in the namespace their class contains, but they are usually difficult to find.

Somehow your double-declaration of friend operator<< is making your code find them, and stop looking into the global namespace for a <<.

To me this looks like a bug. Neither of those "Koenig operators" should be visible to bog-standard unqualified name lookup with types unrelated to the classes they are "contained" in.

MCVE:

#include <iostream>
#include <sstream>

namespace notstd {
struct string {};
}

inline void operator<<(std::wostream &os, const notstd::string &){ return; }

class FakeOstream{};

namespace mynamespace {

class UnusedClass1 {
friend inline void operator<<(FakeOstream &out, const UnusedClass1 &) { return; }
};

class UnusedClass2 {
// comment this line out and the code compiles:
friend inline void operator<<(FakeOstream &out, const UnusedClass2 &) { return; }
};

void test() {
auto mystring = notstd::string{};
std::wostringstream s;
s << mystring; // The errors occur here
}

} // namespace mynamespace

int main(){}

live example.

@T.C. found what appears to be this bug being fixed:

test code

fix in gcc

Overloading operator Cannot bind basic_ostream char lvalue

The problem lies where you are invoking the operator<<, not in its definition.

You are probably calling it in a context like this:

std::ofstream() << "Hello World";

i.e. you are writing into a temporary ostream. That is in contrast with the definition of operator<<, in which you state that you are using a "permanent" (i.e. not a temporary) ostream.

EDIT

After a further examination of the error message, the problem came out to be the missing definition of operator<< for the type enum class Month. Adding such a definition, i.e. std::ostream& operator<<(std::ostream& os, Month m), solved the problem.

error: cannot bind 'std::ostream {aka std::basic_ostream char }' lvalue to 'std::basic_ostream char &&' no template

cout << *serieA[i];

is like:

operator<<(cout, *serieA[i]);

The operator<< cannot be member of your class because it takes the stream as its first parameter.

You need to make it global (non-member function) and change its parameters to stream and a reference to a Team object:

std::ostream& operator<<(std::ostream& os, Team const& team)
{
// put your code here
return os;
}

And if necessary declare it as friend in your Team class:

friend std::ostream& operator<<(std::ostream& os, Team const& team);

You can also define the friend, not just declare in the class if you want:

class Team {
...
bool operator>(Team const&);

friend std::ostream& operator<<(std::ostream& os, Team const& team)
{
// put your code here
return os;
}

private:
...

A good read is operator overloading on cppreference.com

Overloading operator : cannot bind ‘std::basic_istream char ’ lvalue to ‘std::basic_istream char &&’

The error is a bit confusing, but it means there is no operator>> that can be used for sin >> newStudent;

That is because you have declared newStudent as a function (see most vexing parse). The wording of the error is because there is an overload for rvalue streams that accepts anything on the right-hand side:

template<typename CharT, typename TraitsT, typename T>
basic_istream<CharT, TraitsT>&
operator>>(basic_istream<CharT, TraitsT>&& istr, T&&);

and because there is no matching operator for the function type of newStudent it tries to call that overload, which can't bind an rvalue-reference to sin.

The fix is to avoid the most vexing parse:

StudentRecord newStudent;

or:

StudentRecord newStudent{};

or:

StudentRecord newStudent = newStudent();

or similar. With that change newStudent has the right type and so can use your operator>> overload.

error: cannot bind std::ostream lvalue to std::basic_ostream char &&

node is a std::unique_ptr<Node<T>>. You need to dereference it:

out << *node << " ";

error: cannot bind ‘std::basic_ostream char ’ lvalue to ‘std::basic_ostream char &&’

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

cannot bind ‘std::ostream {aka std::basic_ostream char }’ lvalue to ‘std::basic_ostream char &&’

First Case

  A a();

does not construct an object. It declares a function. This parsing problem is known as The Most Vexing Parse.

  A a();
std::cout << a;

works because a is converted to a bool in this case. See Why does pointer to int convert to void* but pointer to function convert to bool? why that works.

Second Case

  A a;
std::cout << a;

does not work because of the way you have defined the operator<< function. You'll have to use

  A a;
a << std::cout;

The operator<< function needs to be a non-member function in order to use:

  A a;
std::cout << a;

See my answer to another SO post to understand why.



Related Topics



Leave a reply



Submit