13

我只是好奇如果我明确地调用会发生什么operator<<std::cout因为我了解到这a.operator()a(). 所以我这样做了,它打印出一些奇怪的东西:

#include <iostream>

using std::cout;

int main()
{
    cout.operator<<("Hello World");
}

Output: 0x80486a0

奇怪的是,它输出了一个地址(地址可能对你不同,但它仍然应该是一个地址)。我在想这是字符串的地址,所以我尝试取消引用它以使其输出字符串:

*( cout.operator<<("Hello World") );

但我得到一个很长的错误

no match for operator* in '*std::cout.std::basic_ostream<...

我觉得这很奇怪。定义中的任何内容都不std::cout会让我相信这会导致任何不同的行为;还考虑到显式调用运算符函数没有区别(或至少应该)。

那么为什么我会得到这个输出呢?为什么在显式调用运算符时收到地址而不是字符串本身?这甚至是内存中的地址还是只是垃圾输出?任何回应表示赞赏。

4

2 回答 2

23

内置字符串的输出运算符,即以 achar const*作为参数的,不是std::ostream. 以 a 为非成员函数的运算符char const*将被称为

operator<< (std::cout, "Hello World");

但是,有一个成员采用 a void const*,它使用十六进制表示法格式化指针的值。operator<< ()当将任何指针显式传递给 的成员时,此成员是最佳匹配std::ostream

取消引用 a 的结果operator<<()不起作用:运算符返回std::ostream&没有一元operator*()重载的 a。如果您打算取消引用该参数,则可以这样称呼它:

std:cout.operator<< (*"Hello World");

但是,这只会使char const*字符串文字衰减到,从而产生一个单独的字符H。字符输出函数也不是成员函数,而整数的输出运算符是,即它会打印H. 对于使用 ASCII 的系统,它将是72.

于 2012-12-24T00:29:06.463 回答
8

我认为这里的问题是,将operator <<C 风格的字符串打印到输出流实际上是一个自由函数,而不是basic_ostream. 但是,basic_ostream确实有一个operator<<函数可以接收 avoid*并打印出它的地址。因此,如果您显式尝试operator<<作为成员函数调用,您调用的是打印出 C 样式字符串地址的版本,而不是打印出字符串字符的自由函数。

你可以通过调用看到这个

operator<< (std::cout, "Hello, world!");

实际上确实打印了字符串。

希望这可以帮助!

于 2012-12-24T00:28:30.363 回答