简体   繁体   English

模糊的C ++运算符重载

[英]Obscure C++ operator overloading

I have the following code: 我有以下代码:

#include <iostream>

using namespace std;

ostream& f(ostream& os) {
    return os << "hi";
}

int main() {
    cout << "hello " << f << endl;
    return 0;
}

And somehow this works - the output is "hello hi". 不知何故,这是有效的 - 输出是“你好”。 How does this get interpreted by the compiler? 这是如何被编译器解释的? I don't understand how a function can be inserted into a stream. 我不明白如何将函数插入到流中。

std::ostream has an operator<< overload that receives a pointer to a function with the signature such as the one you wrote ( number 11 in this list ): std::ostream有一个operator<< overload,它接收一个带有签名的函数的指针,例如你写的那个( 这个列表中的数字11 ):

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

which just calls the given function passing itself as argument. 它只调用给定的函数传递自己作为参数。 This overload (along with several similar others) is there to allow you to implement stream manipulators , ie stuff that you output in the stream with an << and changes the state of the stream from there. 这个重载(以及几个类似的其他)允许您实现流操纵器 ,即您在流中使用<<输出的东西,并从那里更改流的状态。 For example, our version of the (incorrectly) ubiquitous std::endl may be implemented as 例如,我们的(错误的)无处不在的std::endl可以实现为

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

which can then be used exactly as the "regular" std::endl : 然后可以完全用作“常规” std::endl

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

(the actual implementation is templated and a bit more complicated because it has to work even with wide streams, but you got the idea) (实际的实现是模板化的,有点复杂,因为它甚至可以在宽流中工作,但你明白了)

std::ostream::operator<< has an overload which accepts a function as parameter; std::ostream::operator<<有一个重载接受函数作为参数; and the body of that overload is to invoke the function given. 并且该重载的主体是调用给定的函数。

This is exactly how endl works in fact. 这正是endl实际上的工作原理。 endl is actually a function similar to: endl实际上是一个类似于的函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM