2013-03-25 69 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;;前兩行按預期工作。

錯誤信息如下(編譯爲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] 

我無法理解這些錯誤消息告訴我。我會很感激任何幫助。

+0

'操作符[]'是非'const',而是企圖正在取得使用它在''const'其中VECTOR'是非法的。 – hmjd 2013-03-25 21:27:48

回答

5

第一個問題:

使你的程序編譯,只需要使用一個左值參考const爲您operator <<(無論是在friend -declaration並且在函數的定義)的第二個參數:

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

之所以你的程序將無法編譯是你的operator <<超負荷接受左值參考非const作爲第二個參數,並且左值引用非const不能綁定到右值。

由於Vector的兩個實例之間的operator +的結果是臨時值,並且臨時值是右值,因此編譯器無法調用您的operator <<,因此無法解析調用。

第二個問題:

一旦固定的上述問題,你就必須要解決的第二個:你Vector類模板不提供const版本的operator [],所以你改寫operator <<,現在接受對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 2013-03-26 16:19:11

+0

@Arandur:很高興幫助:)最後一個'const'適用於隱式'this'指針,並且基本保證函數不會修改對象(如果您嘗試更改某個數據成員的值'const'成員函數,編譯器會發出一個錯誤 - 除了'mutable'成員之外,但這是另一個故事)。你可以檢查[這個鏈接](http://www.parashift.com/c++-faq/const-member-fns.html)的例子,或谷歌的「C++ const成員函數」,並按照第一個鏈接。或者更好的是,考慮購買一本關於C++的好書。 – 2013-03-26 16:43:54

+0

@Arandur:有關各級C++書籍的列表,請按照[此鏈接](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。祝你好運;) – 2013-03-26 16:44:19

3

更改此:

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

這樣:

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

編譯器告訴你,C++不會讓您綁定的臨時Vectoru + v非constVector&

而且你不修改那個Vector,所以它應該const開始。

+0

謝謝你的回答。但是,我不得不優先考慮Andy Prowl糾正我不知道的問題。 – Arandur 2013-03-26 16:21:25

+0

@Arandur不客氣!我同意 - 他爲你付出了額外的努力。 – 2013-03-26 16:23:45

相關問題