运算符<<如果operator是const,那么重载经常会失败?

时间:2015-12-13 03:29:53

标签: c++ c++11 const overloading ostream

如果我想重载<<运算符以在类上使用cout,它应该如下所示:

template <typename coutT>
friend ostream& operator << (ostream &, const vector3D<coutT>&);

在课堂内,

template <typename coutT>
ostream& operator << (ostream & os,const vector3D<coutT>& v)
{
    os << "x: " << v.x<< "  y: " << v.y << "  z: " << v.z;
    return os; 
}

在外面。请注意第二个操作数的const。 这个代码示例工作得很好。现在问题。

如果我使用字段的getter编写重载函数,而不是直接解决它们(因为operator<<friend),我的编译器会抛出错误:

template <typename coutT>
ostream& operator << (ostream & os,const vector3D<coutT>& v)
{
   os << "x: " << v.getX() << "  y: " << v.getY()  << "  z: " << v.getZ();
   return os; 
}

错误:

  

(VisualStudio2012)errorC2662:&#34;此指针无法转换为&#34; const vector3D&#34;在&#34; vector3D&amp;&#34;&#34;

一个重要的注意事项是删除&#34; const&#34;在第二个操作数,所以它就像

 ostream& operator << (ostream & os,vector3D<coutT>& v){...}

结束了编译错误,但由于我不想改变v,它应该是一个常量。

我还应该提一下,我认为这可能与方法调用有关,但我不确定。

编辑: 所以它被解决了,将const函数声明为const-correctness。 错误消息以无法将const类型转换为非const类型的方式解释它。

顺便说一句:我对快速反应印象深刻。

3 个答案:

答案 0 :(得分:2)

您的问题是您没有标记获取功能const

他们需要看起来像这样:

double getX() const;

答案 1 :(得分:2)

您需要设置访问者函数const

struct V
{
    int getX() const { /* ... */ }
               ^^^^^
};

只能在常量对象值上调用const个成员函数。反过来,const成员函数不能改变对象。因此,const-correctness保证不能通过调用任何成员函数来改变常量值。

答案 2 :(得分:2)

如果要以这种方式使用,请将getter函数声明为const

例如

int getValue() const {
    return x;
}

完整示例:

#include <iostream>
#include <vector>

using namespace std;

class Foo {
    int x;
public:

    Foo(int a) : x(a) {
    }

    int getValue() const {
        return x;
    }

    friend ostream & operator<<(ostream & out, const Foo & foo) {
        return out << foo.getValue();
    }

};

int main() {

    vector<Foo> foo_vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    for (vector<Foo>::iterator it = foo_vec.begin(); it != foo_vec.end(); it++) {
        cout << *it << ", ";
    }

    return 0;
}