错误<<运算符重载返回一个std ::字符串
如果<<
运算符超载的返回类型为std::string
,我很难理解编译器控制错误的原因。你能帮我理解吗?错误<<运算符重载返回一个std ::字符串
波纹管是一个可重现的例子,它给出了一个巨大的错误。
class XY
{
int X__;
int Y__;
public:
XY(int x, int y):X__(x), Y__(y){}
~XY(){}
std::string operator<<(const XY_cartesiano& c)
{
std::stringstream ss;
ss << "{ " << X__ << ", " << Y__ << " }";
return ss.str();
}
int x() const{return X__;}
int y() const{return Y__;}
};
void main()
{
XY a(1,2);
std::cout << a;
}
让我们这样的事情作为一个例子:
cout << "My number is " << 137 << " and I like it a lot." << endl;
这被分析为
((((cout << "My number is ") << 137) << " and I like it a lot.") << endl);
尤其注意到表达cout << "My number is "
必须评估的东西,这样,当然后我们尝试插入137与<< 137
的含义是“请137并将其发送到cout
”。
想象一下,如果cout << "My number is "
要返回string
。在这种情况下,<< 137
位会尝试在左侧的string
与右侧的int
之间使用<<
运算符,这在C++中没有很好定义。
约定是让流插入运算符operator <<
返回对左侧流的引用,以便这些操作链接良好。这样,<< 137
左侧的东西本身就是cout
,所以上面的代码基本上是一系列链接调用来插入cout
。因此,这些功能的签名通常如下所示:
ostream& operator<< (ostream& out, const ObjectType& myObject) {
// ... do something to insert myObject into out ... //
return out;
}
现在,一切正常链接。注意这个函数是一个自由函数,不是成员函数,左边是ostream
类型,右边有你的类的类型。这是做这件事的传统方法,因为如果你尝试将operator <<
作为成员函数进行重载,那么左边将是你类类型的操作数,这与流插入应该如何工作相反。如果您需要专门访问类的私有领域在实现此功能的过程中,使之成为朋友:
class XY {
public:
...
friend ostream& operator<< (ostream& out, const XY& myXY);
};
ostream& operator<< (ostream& out, const XY &myXY) {
...
return out;
}
正确方法重载<<
运营商,你的情况是
ostream& operator<<(ostream& os, const XY& c)
{
os << c.X__ <<" "<< c.Y__ ;
return os;
}
实际上,如果'os'设置了其宽度修饰符(或其他瞬态流修饰符),以便输出不会部分损坏,那么使用内部'ostringstream'可以构建一次打印的整个字符串。 – templatetypedef
你有重载operator<<
的方式与当您打算将对象(如std::cout
)使用该操作符时必须遵循的约定不符。
事实上,您的operator<<
的签名与流无关!它只是XY
的成员函数,它需要另一个XY
(它不使用它),返回一个字符串并具有一个非名称。这里是你如何在理论上称之为:
XY a(1,2);
XY b(1,2);
std::string x = (a << b);
超载operator<<
为使用流,正确的方法是使运营商在非成员函数中,添加一个流的参考参数和返回流参照流参数。你也不需要字符串流;你直接写入到流你:
#include <iostream>
class XY
{
int x;
int y;
public:
XY(int x, int y) : x(x), y(y) {}
int X() const { return x; }
int Y() const { return y; }
};
std::ostream& operator<<(std::ostream& os, XY const& c)
{
os << "{ " << c.X() << ", " << c.Y() << " }";
return os;
}
int main()
{
XY a(1,2);
std::cout << a;
}
这是没有问题的,但包含两个连续的下划线('X__','Y__')和名称的名称以下划线跟着一个大写字母开头保留供实施使用。不要在你的代码中使用它们。 –