Overload operator <<: cannot bind 'std :: basic_ostream <char> lvalue to' std :: basic_ostream <char> &&

Searching for the name of this question gives me several people citing the same error, but under different circumstances, and, unfortunately, the answers that are given there are specific to their situation, and I don’t see how they can help me.

I am trying to overload operator<< for a template class. The following is a test case:

vector.h:

 #ifndef __INCL_VECTOR_H__ #define __INCL_VECTOR_H__ #include <array> template < class T, unsigned int N > class Vector { public: Vector(); Vector( std::array< T, N > ); template < class U, unsigned int M > friend Vector< U, M > operator+ ( const Vector< U, M >&, const Vector< U, M >& ); template < class U, unsigned int M > friend std::ostream& operator<< ( std::ostream&, Vector< U, M >& ); T& operator[] ( const unsigned int& ); protected: std::array< T, N > _values; }; #include "Vector.hpp" #endif 

Vector.hpp:

 #include "Vector.h" #include <iostream> template < class T, unsigned int N > Vector< T, N >::Vector() { } template < class T, unsigned int N > Vector< T, N >::Vector( std::array< T, N > otherArray ) { _values = *( new std::array< T, N >( otherArray ) ); } template < class U, unsigned int M > Vector< U, M > operator+ ( const Vector< U, M > &lhVector, const Vector< U, M > &rhVector ) { Vector< U, M > sumVector; for( unsigned int i = 0; i < M; i++ ) sumVector[i] = lhVector[i] + rhVector[i]; return sumVector; } template < class U, unsigned int M > std::ostream& operator<< ( std::ostream &out, Vector< U, M > &cVector ) { out << "< "; for( int i = M - 1; i >= 0; i-- ) { out << cVector[i]; if( i ) out << ", "; } out << " >"; return out; } template < class T, unsigned int N > T& Vector< T, N >::operator[] ( const unsigned int &index ) { return _values[ index ]; } 

vectorTest.cpp:

 #include "Vector.h" #include <iostream> #include <array> using namespace std; int main( int argc, char* argv[] ) { Vector< int, 3 > u( array< int, 3 > { 1, 4, 2 } ); Vector< int, 3 > v( array< int, 3 > { -2, 3, -1 } ); cout << "u = " << u << endl; cout << "v = " << v << endl; cout << "u + v = " << u + v << endl; return 0; } 

The line causing the error is cout << "u + v = " << u + v << endl; ; the previous two lines work as expected.

The error message is as follows (compilation as g++ -std=c++11 Vector.h vectorTest.cpp ):

 vectorTest.cpp: In function 'int main(int, char**)': vectorTest.cpp:15:31: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&' In file included from /usr/include/c++/4.7/iostream:40:0, from Vector.hpp:2, from Vector.h:34: /usr/include/c++/4.7/ostream:600:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Vector<int, 3u>]' In file included from Vector.h:34:0: Vector.hpp: In instantiation of 'Vector<U, M> operator+(const Vector<U, M>&, const Vector<U, M>&) [with U = int; unsigned int M = 3u]': vectorTest.cpp:15:31: required from here Vector.hpp:40:9: error: passing 'const Vector<int, 3u>' as 'this' argument of 'T& Vector<T, N>::operator[](const unsigned int&) [with T = int; unsigned int N = 3u]' discards qualifiers [-fpermissive] Vector.hpp:40:9: error: passing 'const Vector<int, 3u>' as 'this' argument of 'T& Vector<T, N>::operator[](const unsigned int&) [with T = int; unsigned int N = 3u]' discards qualifiers [-fpermissive] 

I cannot understand what the error messages say about this. I would appreciate any help.

+1
source share
2 answers

FIRST PROBLEM:

To compile your program, simply use the lvalue link for const as the second parameter of your operator << (both in friend declaration and in the definition of this function):

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

The reason your program will not compile is because your operator << overload accepts a non- const lvalue reference as its second argument, and non- const references lvalue cannot bind to rvalues.

Since the result of operator + between two Vector instances is temporary and rvalue is temporary, the compiler cannot call your operator << and therefore cannot resolve the call.

SECOND PROBLEM:

Once you have fixed the above problem, you will have to solve the second: your Vector template template does not provide a version of const operator [] , so your rewritten operator << , which now accepts a link to the const vector, will not be able to access vector 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 ]; } 
+5
source

Change this:

 std::ostream& operator<< ( std::ostream&, Vector< U, M >& ); 

:

 std::ostream& operator<< ( std::ostream&, const Vector< U, M >& ); // ^^^^^ 

The compiler tells you that C ++ will not allow you to bind a temporary Vector such as u + v to a non-const Vector& .

And you do not change this Vector , so for a start there must be const .

+3
source

Source: https://habr.com/ru/post/945012/


All Articles