根据Can't Overload operator<< as member function
当作为成员函数重载时,<< <<被解释为 a.operator <<(b),因此它只需要一个显式参数(此为 一个隐藏的参数)。
因为这需要重载作为用作类的类的一部分 左手操作数,对于普通的ostream等无效。它 将要求您的重载成为ostream类的一部分,而不是 你班上的一部分由于您不允许修改ostream类, 你不能那样做。剩下的只是全局过载 替代。
我知道例如:
friend std::ostream& operator<< (std::ostream &out, const Obj &obj);
就像一个函数,该函数接受一个ostream对象和您要打印的某个对象,然后返回一个ostream对象。
但是我不知道cout << obj
会如何调用此函数。
cout << obj
不会做cout.operator<<(obj)
之类的事情,这正是我们不想要的吗?那么,为什么实际上要调用该函数呢?为什么它允许返回值返回到cout
?
编辑:
我以前已经读过What are the basic rules and idioms for operator overloading?,它指出
“应用于对象x和y的二进制中缀运算符@被称为 作为operator @(x,y)或x.operator @(y).4“
这提供了一些进一步的说明,但是我看不出它如何回答我的问题。
答案 0 :(得分:2)
这并不是您做的很好,就是您引用的答案。
操作员重载可以是成员,也可以是非成员。
例如,anOstream << aT
可以用ostream& ostream::operator<<(T)
(或类似名称)或自由函数ostream& operator<<(ostream&, T)
来解析。这些都可以被调用。就是这样。这就是标准所说的。
由于我们无法在ostream
中添加内容,因此后者就是我们的处理方式(尽管对于您自己的类型,这完全取决于您)。
请注意,对于这些示例,我如何选择ostream&
的返回类型;这就是“返回值返回到cout
”的方式:左侧操作数只是通过引用返回。
答案 1 :(得分:2)
如果存在,编译器将调用cout.operator <<(obj),但如果不存在,它将寻找兼容的全局函数。
例如在它下面将调用成员函数。但是,如果将其注释掉,它将调用全局函数。
#include <iostream>
class Ostr;
class Obj {
public:
void print(Ostr& os) const;
};
class Ostr {
public:
Ostr& operator<<(const Obj& obj){
std::cout << "member";
obj.print(*this);
return *this;
}
Ostr& operator<<(const char* obj){
std::cout << obj;
return *this;
}
};
void Obj::print(Ostr& os) const {
os << "Obj";
}
template<class T>
auto operator<<(Ostr& os, const T& t) -> decltype(t.print(os), os) {
os << "global";
t.print(os);
return os;
}
int main() {
Obj obj;
Ostr ostr;
ostr << obj;
return 0;
}