我试图对这样的简单结构进行覆盖:
struct Node {
int data1;
int data2;
ostream& operator<<(ostream &o, const Node &n)
{
o << "(a: " << data1 << ", b: " << data2 << ")";
return o;
}
};
我得到:错误C2804:'operator&lt;&lt;'参数太多
所以,如果我删除第二个参数:
ostream& operator<<(ostream &o)
然后我得到:错误:二进制'&lt;&lt;&lt;' :找不到哪个运算符采用'const Node'类型的右手操作数
这里发生了什么?
答案 0 :(得分:3)
std::ostream& operator<<(std::ostream&, ...)
需要是一个免费功能。
将它移到课堂外,它会起作用。
之所以如此,是因为在类中定义operator<<(std::ostream&)
(或其他二元运算符)意味着该对象是LHS操作数。你必须像以下一样疯狂地写作:
Node << std::cout;
答案 1 :(得分:3)
operator<<
需要两个操作数。有两种方法可以在两种类型之间定义operator<<
重载函数。
作为会员功能。这就是operator<<
与某些基本类型之间的std::basic_ostream
重载的定义方式。当您使用std:cout << 10;
时,它会被解析为重载运算符std::basic_ostream<char>::operator<<(int)
当您将其定义为成员函数时,运算符的LHS是类的实例。运算符的RHS是函数的参数。这就是为什么当你把它定义为成员函数时,它只能有一个参数。
作为免费功能。这就是定义operator<<
和自定义类型之间std::basic_ostream
重载的方式。这些函数必须有两个参数。第一个参数是运算符的LHS,第二个参数是运算符的RHS。
出于这个原因,您必须将operator<<
和您的类之间的std::ostream
重载定义为自由函数,其中std::ostream&
为第一个参数类型,Node const&
为第二种参数类型。
std::ostream& operator<<(std:ostream& os, Node const& node);
在这些时候,我希望标准库实现了一个功能:
template <typename T>
std::ostream& operator<<(std::ostream& os, T const& t)
{
return t.serialize(os);
}
然后,任何类都可以提供函数
std::ostream& serialize(std::ostream& os) const;
并准备像std::ostream
一样使用所有基本类型。