由于我从C转换到C ++,我对STL的格式输出有疑问。 ostreams如何告诉另一种基本类型?
在C中,它的printf和格式化字符串非常简单,但在C ++中,ostreams会以某种方式自动区分基本类型。这让我很困惑。
例如,在以下代码中,
int i;
float f;
std::cout << i << std::endl;
std::cout << f << std::endl;
cout如何“知道” i 是一个int而 f 是一个浮点数?
答案 0 :(得分:7)
编译器将运算符转换为函数调用。那么
std::cout << i
变为
operator<<(std::cout, i)
某些地方深埋在标准库标题的内部,有函数声明(功能相当于):
std::ostream& operator<<(std::ostream& o, int i);
std::ostream& operator<<(std::ostream& o, double d);
也就是说,operator<<
已超载。进行函数调用时,编译器会选择与传入的参数最匹配的函数重载。
如果是std::cout << i
,则会选择int
重载。如果是std::cout<<d
,则会选择double
重载。
你可以通过一个人为的例子很简单地看到函数重载:
#include <stdio.h>
void print(int i) {printf("%d\n", i);}
void print(double d) {printf("%f\n", d);}
int main()
{
int j=5;
double f=7.7;
print(j);
print(f);
}
制作输出:
5
7.700000
亲自尝试:http://ideone.com/grlZl。
编辑:正如Jesse Good指出的那样,有问题的功能是成员函数。我们真的有:
std::cout << i
变为
std::cout.operator<<(i)
在标题中有声明(相当于):
class ostream {
ostream& operator<<(int i);
ostream& operator<<(double d);
...
};
然而,同样的基本观点仍然存在。
答案 1 :(得分:3)
有运营商&lt;&lt;每种类型的重载(int,float等)。
然后编译器将在编译时选择正确的编译器。
通常,运营商&lt;&lt;格式为std::ostream& operator<<(std::ostream& stream, int number )
,其中函数是std命名空间中定义的全局函数。您可以通过在自己的命名空间中声明它来覆盖此函数的定义(这是通过Argument Dependent Lookup完成的。)
函数返回对流的引用这一事实意味着您可以将它们串在一起。请记住,无论何时看到运算符&lt;&lt;,它实际上只是一个函数调用。
如果你想看看,并且你正在使用VS,请打开
C:\ Program Files(x86)\ Microsoft Visual Studio 9.0 \ VC \ include \ ostream。
如果你很好奇,你会找到所有的定义。
答案 2 :(得分:2)
第二个参数的重载分辨率为operator<<
答案 3 :(得分:1)
函数重载是编译时多态的一种形式。一个简单的例子:
void times_two(int& x) { x *= 2; }
void times_two(double& x) { x *= 2; }
int i = 2;
double d = 2.5;
times_two(i); // i now 4
times_two(d); // d now 5.0
对于std::ostream
这样的std::cout
,operator<<()
函数以类似方式重载。来自GCC 3.4.4附带的标准库:
__ostream_type&
operator<<(int __n);
__ostream_type&
operator<<(double __f);
答案 4 :(得分:0)
这是一个重载的ostream运算符&lt;&lt ;.在c ++中,您可以根据它的参数重载函数名称。这基本上就是这里发生的事情。 http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/