cout如何区分基本类型?

时间:2012-05-15 01:31:30

标签: c++ types cout

由于我从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 是一个浮点数?

5 个答案:

答案 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::coutoperator<<()函数以类似方式重载。来自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/