为什么在std :: cout上显式调用operator <<会导致意外输出?

tem*_*boy 12 c++ string iostream operator-overloading

我只是好奇如果我明确地打电话会发生什么operator<<,std::cout因为我知道它a.operator()与...完全相同a().所以我这样做,它打印出一些奇怪的东西:

#include <iostream>

using std::cout;

int main()
{
    cout.operator<<("Hello World");
}
Run Code Online (Sandbox Code Playgroud)

Output: 0x80486a0

奇怪的是,它输出一个地址(地址可能不同,但它应该仍然是一个地址).我认为这是字符串的地址所以我尝试解除引用它以使其输出字符串:

*( cout.operator<<("Hello World") );
Run Code Online (Sandbox Code Playgroud)

但是我得到了很长的错误

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

我觉得这很奇怪.没有任何std::cout定义会让我相信这会导致任何不同的行为; 另外,明确调用运算符函数没有区别(或至少应该).

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

Die*_*ühl 23

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

operator<< (std::cout, "Hello World");
Run Code Online (Sandbox Code Playgroud)

但是,有一个成员void const*使用十六进制表示法来格式化指针的值.该成员是最好的搭配传递任何指针时明确为成员operator<< ()std::ostream.

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

std:cout.operator<< (*"Hello World");
Run Code Online (Sandbox Code Playgroud)

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


tem*_*def 7

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

你可以通过电话看到这个

operator<< (std::cout, "Hello, world!");
Run Code Online (Sandbox Code Playgroud)

这实际上打印字符串.

希望这可以帮助!