1

自从我从 C 转移到 C++ 后,我对 STL 的格式化输出有疑问。ostreams 如何区分一种基本类型和另一种?

在具有 printf 和格式化字符串的 C 中,它非常简单,但在 C++ ostreams 中以某种方式自动区分基本类型。这让我很困惑。

例如,在下面的代码中,

int i;
float f;

std::cout << i << std::endl;
std::cout << f << std::endl;

cout 如何“知道” i是 int 而f是 float?

4

5 回答 5

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 << iint选择重载。在 的情况下std::cout<<ddouble选择重载。

您可以通过一个人为的示例相当简单地看到函数重载的作用:

#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);
    ...
};

然而,同样的基本思想也成立。

于 2012-05-15T01:48:41.807 回答
3

每种类型(int、float 等)都有 operator<< 重载。然后编译器将在编译时选择正确的那个。通常,运算符<< 具有形式std::ostream& operator<<(std::ostream& stream, int number ),其中函数是定义在 std 命名空间中的全局函数。您可以通过在您自己的命名空间中声明此函数来覆盖该函数的定义(这是通过 Argument Dependent Lookup 完成的)。

该函数返回对流的引用这一事实意味着您可以将它们串在一起。请记住,每当您看到 operator<<,它实际上只是一个函数调用。

如果你想看看,并且你正在使用 VS,打开

C:\Program 文件 (x86)\Microsoft Visual Studio 9.0\VC\include\ostream。

如果你好奇的话,你会在那里找到所有的定义。

于 2012-05-15T01:34:43.750 回答
2

第二个参数的重载决议operator<<

于 2012-05-15T01:33:34.887 回答
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::ostreams such的情况下std::coutoperator<<()函数以类似的方式重载。从 GCC 3.4.4 附带的标准库中:

__ostream_type&
operator<<(int __n);

__ostream_type&
operator<<(double __f);
于 2012-05-15T01:55:03.297 回答
0

这是一个重载的 ostream 运算符 <<。在 c++ 中,您可以根据其参数重载函数名称。这基本上就是这里发生的事情。http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/

于 2012-05-15T01:34:42.540 回答