如果运算符是常量,运算符 << 重载通常会失败?
operator << overloading often fails if operator is const?
如果我想重载 <<
运算符以在 class 上使用 cout
,它应该如下所示:
template <typename coutT>
friend ostream& operator << (ostream &, const vector3D<coutT>&);
在class里面,并且
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: "this-pointer cannot be converted from "const vector3D" in "vector3D&""
一个重要的注意事项是删除第二个操作数的 "const" 以便它像
ostream& operator << (ostream & os,vector3D<coutT>& v){...}
结束编译错误,但因为我不想改变v
,它应该是一个常量。
我还应该提到,我认为这可能与一般的方法调用有关,但我不确定。
编辑:
所以解决了,将函数声明为 const 坚持 const 正确性。
错误消息以无法将 const 类型转换为非常量类型的方式对其进行解释。
顺便说一句:实际上,我对快速回复印象深刻。
你的问题是你没有标记get函数const
:
他们需要看起来像这样:
double getX() const;
您需要创建访问函数 const
:
struct V
{
int getX() const { /* ... */ }
^^^^^
};
只能对常量对象值调用 const
成员函数。反过来,const 成员函数不能改变对象。因此 const-correctness 保证常量值不能通过调用它的任何成员函数来改变。
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;
}
如果我想重载 <<
运算符以在 class 上使用 cout
,它应该如下所示:
template <typename coutT>
friend ostream& operator << (ostream &, const vector3D<coutT>&);
在class里面,并且
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: "this-pointer cannot be converted from "const vector3D" in "vector3D&""
一个重要的注意事项是删除第二个操作数的 "const" 以便它像
ostream& operator << (ostream & os,vector3D<coutT>& v){...}
结束编译错误,但因为我不想改变v
,它应该是一个常量。
我还应该提到,我认为这可能与一般的方法调用有关,但我不确定。
编辑: 所以解决了,将函数声明为 const 坚持 const 正确性。 错误消息以无法将 const 类型转换为非常量类型的方式对其进行解释。
顺便说一句:实际上,我对快速回复印象深刻。
你的问题是你没有标记get函数const
:
他们需要看起来像这样:
double getX() const;
您需要创建访问函数 const
:
struct V
{
int getX() const { /* ... */ }
^^^^^
};
只能对常量对象值调用 const
成员函数。反过来,const 成员函数不能改变对象。因此 const-correctness 保证常量值不能通过调用它的任何成员函数来改变。
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;
}