3

我正在学习 C++,在用户定义的输出流操纵器部分,我被卡住了。这是示例代码:

    #include <iostream>
     using std::cout;
     using std::flush;
     using std::ostream;

    ostream& endLine( ostream& output )
    {
      return output << '\n' << flush;
    }

    int main()
    {
       cout << "Testing:" << endLine;
       return 0;
    }

我的问题是,在 endLine 的定义中,有一个论点。但是在 main 函数中,为什么它只有 endLine 没有括号和相应的参数。

4

3 回答 3

2

std::basic_ostream有几个重载operator<<,其中一个具有以下签名:

basic_ostream& operator<<( basic_ostream& st, 
                       std::basic_ostream& (*func)(std::basic_ostream&) );

也就是说,这个函数接受一个指针,指向一个既接受又返回的函数std::ios_base。该方法由该函数调用并被合并到输入/输出操作中。从而使这成为可能:

std::cout << endLine;

所以会发生什么endLine被转换成一个函数指针,一个换行符将被写入流,然后是一个刷新操作。

于 2013-07-05T01:32:17.343 回答
2

std::ostream 有一个重载,operator<<它接受一个指向函数的指针(或者可以调用的类似函数),该函数接受指针,并调用函数,将自身作为参数传递给函数:

std::ostream &operator<<(std::ostream &os, ostream &(*f)(ostream &os)) { 
    return f(*this);
}

内置的版本ostream来自std::ios_base(这是它用于参数和返回的类型),但如果您尝试编写自己的版本,您通常希望使用它std::ostream

于 2013-07-05T01:33:54.447 回答
0

cout的左移运算符调用endLinewithcout作为参数。写函数名时不需要调用函数(技术上是函数指针);您可以将它们作为值传递,并让其他代码稍后调用它们。

于 2013-07-05T01:33:11.893 回答