2013-03-25 162 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

相关问题