调用一个操纵 ostream 的函数不需要括号。C++

3

我知道一个函数不能在没有括号的情况下被调用,但是,假设我有这样一段源代码:

#include<iostream>
using namespace std;

ostream& test(ostream& os){
os.setf(ios_base::floatfield);
return os;
}

int main(){
cout<<endl<<scientific<<111.123456789;
cout<<endl<<test<<111.123456789;
}

   /// Output:
   /// 1.11235e+002
   /// 111.123

左移运算符没有重载,但是当我在main函数中的cout里调用test(ostream& os)函数时,它不需要任何圆括号。我的问题是为什么?


10
左移运算符没有重载 - 是的,有重载。 - Konrad Rudolph
你可以在不使用括号的情况下调用函数(即函数在源代码中不必像函数一样看起来),这是我对C ++的许多事情之一,仍然,cout确实“重载了左移运算符”-这就是你正在看的; 这就是它的工作原理。例如:[iostream.h](http://www.opensource.apple.com/source/gcc/gcc-937.2/libio/iostream.h):`ostream&operator <<(char c);` PS:我讨厌C ++的另一件事是省略“h”头文件后缀;) - paulsm4
@paulsm4 你这个异教徒!.hpp是用于C++的。 - RamblingMad
@paulsm4:“我讨厌C++的众多事情之一”-也许您正在忽略使用模板(甚至宏)使用与int等相同的值语义符号处理不同类型的效用(和美学)?……这非常优雅和强大。 - Tony Delroy
2个回答

6

左移操作符没有重载。

实际上有,它在<ostream>中被定义。

它使用了与endlscientific相同的技术。有一个接受函数指针的重载,当写入流时调用函数指针。

basic_ostream有这些接受函数指针的成员函数:

// 27.7.3.6 Formatted output:
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))
{ return pf(*this); }

basic_ostream<charT,traits>&
operator<<(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&))
{ return pf(*this); }

basic_ostream<charT,traits>&
operator<<(ios_base& (*pf)(ios_base&))
{ return pf(*this); }

cout << test使用了上述两个overloads中的第一个,它等同于cout.operator<<(&test),这会执行return test(*this);,所以调用发生在重载的operator<<内部。


6

ostream针对这种情况进行了 << 运算符的重载:

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

调用func(*this);。这些重载用于实现输出I/O操作符,例如std::endl。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接