2013-03-25 3 views
1

이 질문의 제목을 검색하면 동일한 오류를 인용하는 사람들이 많지만, 불행하게도 거기에 제공된 답변은 상황에 따라 다르며 어떻게 도와 줄 수 있는지 알지 못합니다.연산자 오버로딩 << : std :: basic_ostream <char>을 'std :: basic_ostream <char> &&'로 바인딩 할 수 없습니다.

템플릿 클래스에 operator<<을 오버로드하려고합니다.

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

오류가 발생 라인 다음은 테스트 케이스 인 cout << "u + v = " << u + v << endl;; 이전 두 줄은 예상대로 작동합니다.

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] 

나는 이러한 오류 메시지가 나에게 말하고있는 것을 이해 드릴 수 없습니다 :

오류 메시지는 다음과 같이 (g++ -std=c++11 Vector.h vectorTest.cpp로 컴파일)입니다. 어떤 도움을 주시면 감사하겠습니다.

+0

연산자 '[]'비 'const'이지만 시도는''const' Vector'에 사용하게되고있는 불법입니다. – hmjd

답변

5

첫 번째 문제 :

:

은 당신의 operator << (모두 friend -declaration에서 그 함수의 정의)의 두 번째 매개 변수로 const에 좌변 참조를 사용하여 프로그램 컴파일을 만들려면

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

컴파일되지 않습니다 프로그램이 operator << 당신의 과부하가 비 0123에 대한 두 번째 인수로 const을이 비 좌변 참조 및 좌변 참조를 허용하는지 왜 이유수 없습니다 rvalues에 바인딩합니다. Vectoroperator + 둘 사이의 인스턴스의 결과 이후

는 일시적이며, 임시가를 rvalue이며, 컴파일러는 당신의 operator <<를 호출 할 수 없습니다, 따라서 전화를 해결할 수 없습니다.

두 번째 문제 :있는 지금, 그래서 당신의 operator << 다시, operator [] 당신의 Vector 클래스 템플릿이 제공하지 않는 const 버전 : 위의 문제를 해결하면

, 당신은 두 번째를 해결해야합니다 const 벡터에 대한 참조를 허용하지만 벡터 요소에 액세스 할 수 없습니다.

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

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

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

    // ... 
}; 

그리고 물론 해당 정의

:

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

직접적인 문제를 해결하는 데 필요한 것을 넘어서서 고맙습니다. 내 코드는 당신이 제안한 조정을 한 후에 완벽하게 컴파일되고 실행됩니다. 질문 : 함수 헤더'T const & operator [] (const unsigned int &) const'에서 첫 번째 const가 무엇인지, 두 번째 것이 무엇인지 알고 있지만 종료. 저를위한 마지막 const의 기능을 설명해 주시겠습니까? 아니면 이해를 얻을 수있는 곳으로 링크를 보내 주시겠습니까? – Arandur

+0

@Arandur : Glad it help :) 마지막'const'는 암시적인'this' 포인터에 적용되며, 기본적으로 함수가 객체를 수정하지 않을 것임을 보증합니다 (만약 당신이 데이터 멤버의 값을 'const' 멤버 함수를 사용하면, 컴파일러는'mutable' 멤버를 제외하고는 에러를 발생시킬 것입니다. 예를 들어 [이 링크] (http://www.parashift.com/c++-faq/const-member-fns.html)를 확인하거나 "C++ const 멤버 함수"에 대해 google을 사용하고 첫 번째 링크를 따를 수 있습니다. 아니면 C++에 대한 훌륭한 입문서를 구입하는 것이 좋습니다. –

+0

@Arandur : 모든 레벨의 C++ 서적 목록을 보려면 [이 링크] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)를 따르십시오. 그리고 행운을 빕니다;) –

3

변경이이에

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

:

컴파일러는 C++이 임시 Vector 같은 A와 u + v으로 const가 아닌 바인딩 못하게 함을 말하고있다
std::ostream& operator<< (std::ostream&, const Vector< U, M >&); 
//          ^^^^^ 

Vector& .

그리고 Vector을 수정하지 않으므로 이어야합니다. 먼저 const이되어야합니다.

+0

답변 해 주셔서 감사합니다. 그러나 나는 내가 가지고 있다는 것을 모르는 문제를 해결하기 위해 Andy Prowl을 선호해야만했다. – Arandur

+0

@Arandur 당신을 환영합니다! 나는 동의한다 - 그는 당신을 위해 여분 마일을 갔다. –

관련 문제