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
C++: Argument Passing "Passed by Reference"
Opencv Error: Assertion Failed (Size.Width>0 && Size.Height>0) Simple Code
How to Detect/Avoid Memory Leaks in Your (Unmanaged) Code
How to Initialize C++ Object Member Variables in the Constructor
Does Std::List::Remove Method Call Destructor of Each Removed Element
How to Define a Template Function Within a Template Class Outside of the Class Definition
Why Does C++ Allow an Integer to Be Assigned to a String
Stdafx + Header File - Order of Inclusion in Mfc Application
How to Remove All the Occurrences of a Char in C++ String
How to Use Visual Studio 2010's C++ Compiler with Visual Studio 2008's C++ Runtime Library
What's This C++ Syntax That Puts a Brace-Surrounded Block Where an Expression Is Expected
G++ "Calling" a Function Without Parenthesis (Not F() But F; ). Why Does It Always Return 1
What Is the Point of a Private Pure Virtual Function
What Does '&' Do in a C++ Declaration
How to Best Handle Dynamic Multi-Dimensional Arrays in C/C++