我很清楚,如果我明确地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
定义中的任何内容都不会让我相信这会导致任何不同的行为;同样明确调用运算符函数没有区别(或者至少应该)。
那为什么我得到这个输出?为什么在显式调用运算符时我收到的是地址而不是字符串本身?这甚至是内存中的地址还是垃圾输出?任何回复都表示赞赏。
答案 0 :(得分:22)
内置字符串的输出运算符,即以char const*
为参数的on,不是std::ostream
的成员。采用char const*
的运算符是非成员函数,将被称为
operator<< (std::cout, "Hello World");
然而,有一个成员使用void const*
使用十六进制表示法格式化指针的值。将任何指针明确传递给operator<< ()
的成员std::ostream
时,此成员是最佳匹配。
取消引用operator<<()
的结果不起作用:运算符返回std::ostream&
,其中没有一元operator*()
重载。如果你打算取消引用这个论点,你可以这样称呼它:
std:cout.operator<< (*"Hello World");
但是,这只会将字符串文字的char const*
衰减,从而产生一个单独的字符H
。字符输出函数也不是成员函数,而整数的输出运算符是,即它将打印字符值H
。对于使用ASCII的系统,它将是72
。
答案 1 :(得分:7)
我认为这里的问题是将C样式字符串打印到输出流的operator <<
实际上是自由函数,而不是basic_ostream
的成员函数。但是,basic_ostream
确实具有operator<<
函数,该函数接收void*
并打印出其地址。因此,如果您明确尝试将operator<<
作为成员函数进行调用,那么您将调用打印出C样式字符串地址的版本,而不是将字符串打印出来的自由函数。
你可以通过调用
来看到这一点operator<< (std::cout, "Hello, world!");
实际上 打印字符串。
希望这有帮助!