模糊的C++运算符重载



我有以下代码:

#include <iostream>
using namespace std;
ostream& f(ostream& os) {
    return os << "hi";
}
int main() {
    cout << "hello " << f << endl;
    return 0;
}

不知何故,这是有效的——输出是"你好"。编译器如何对此进行解释?我不明白如何将函数插入流中。

std::ostream有一个operator<<重载,它接收一个指向具有签名的函数的指针,例如您编写的签名(此列表中的编号11):

basic_ostream& operator<<(
    std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );

它只是调用将自身作为参数传递的给定函数。这个重载(以及其他几个类似的重载)允许您实现流操纵器,即使用<<在流中输出的内容,并从此更改流的状态。例如,我们版本的(错误地)普遍存在的std::endl可能被实现为

std::ostream &myendl(std::ostream &s) {
    s<<'n';
    s.flush();
    return s;
}

然后可以精确地用作"常规"std::endl:

std::cout<<"Hello, World!"<<myendl;

(实际的实现是模板化的,而且有点复杂,因为它甚至必须在宽流中工作,但你已经明白了)

std::ostream::operator<<有一个重载,它接受一个函数作为参数;并且该重载的主体是调用给定的函数。

事实上,endl就是这样工作的。endl实际上是一个类似于的函数

ostream &endl(ostream &os)
{
    os << 'n'; 
    os.flush(); 
    return os;
}

最新更新