template boy
template boy

Reputation: 10480

Why does explicitly calling operator<< on std::cout cause unexpected output?

I was simply curious about what would happen if I called operator<< on std::cout explicitly because I learnt that a.operator() is exactly the same as a(). So I do it and it prints something weird:

#include <iostream>

using std::cout;

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

Output: 0x80486a0

Oddly, it outputs an address (the address may be different for you but it should still be an address). I'm thinking this is the address of the string so I try dereferencing it to get it to output the string:

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

But I get a very long error

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

I think this is pretty weird. Nothing of the std::cout definition would lead me to believe this would cause any different behavior; also given the fact that explicitly calling the operator function makes no difference (or should at least).

So why am I getting this output? Why am I receiving an address instead of the string itself when calling the operator explicitly? Is this even the address in memory or just garbage output? Any responses are appreciated.

Upvotes: 13

Views: 2478

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

The output operator for built-in strings, i.e., the on taking a char const* as argument, isn't a member of std::ostream. The operator taking a char const* is a non-member function would be called as

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

There is, however, a member taking a void const* which formats the value of the pointer using hex notation. This member is the best match when passing any pointer explicitly to a member operator<< () of std::ostream.

Dereferencing the results of a the operator<<() doesn't work: The operators return a std::ostream& which doesn't have a unary operator*() overloaded. If you meant to dereference the argument, you'd call it like so:

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

However, this would just derference the char const* the string literal decays to, yielding an individual character H. The character output function isn't a member function, either, while the output operators for integers are, i.e., it would print character value of H. For a system using ASCII it would be 72.

Upvotes: 23

templatetypedef
templatetypedef

Reputation: 372814

I think the issue here is that the operator << that prints a C-style string to an output stream is actually a free function, not a member function of basic_ostream. However, basic_ostream does have an operator<< function that takes in a void* and prints out its address. As a result, if you explicitly try calling operator<< as a member function, you're calling the version that prints out an address of the C-style string, rather than the free function that prints out the characters a string.

You can see this by calling

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

Which actually does print the string.

Hope this helps!

Upvotes: 8

Related Questions