5

According to the top answer to this question, cout << expr is equivalent to cout.operator<<(expr).

According to responses to this question, the statement above is untrue.

According to my own testing, cout.operator<<() is the same as cout << when given an integer. When given a float, cout.operator<<() coerces it to an integer. When given a string literal, as in cout.operator<<("hello world"), it outputs what appears to be a memory address. And when given a variable holding a std::string, it gives a compiler error.

Could anyone give a beginner-to-intermediate-level explanation of what's going on?

  • "*`cout << expr` is equivalent of `cout.operator<<(expr)`*" is not universally true. The answer from the 2nd question + 1st comment explain that. Not sure if that counts as duplicate... Perhaps this would help: https://stackoverflow.com/questions/36809463/is-there-any-advantage-to-implementing-functions-as-free-functions-rather-than-m/36809565#36809565 – luk32 Jun 07 '17 at 14:06

2 Answers2

5

It depends on expr.

The answers to both questions are speaking to that specific case, not a blanket guarantee.

In fact, some of the operator<<s are free functions, and some are member functions.

Consult your favourite C++ reference to find out which.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
3

The equivalency of cout << expr and cout.operator<<(expr) depends on what expr is.

If it lands up being a "built in" type, that cout "knows" about, then yes, it is equivalent to cout.operator<<(expr) (a member function).

If it is a "user type" (and std::string counts here), then it is an overloaded non-member method with a signature akin to std::ostream& operator<<(std::ostream&, const std::string&); etc.

Why does cout.operator<<("hello world") print a memory address?

The best member method overload to the above (since it is being forced to use the member method, is ostream& operator<<(const void* value); which outputs the value of the pointer (not what is being pointed to).

By contrast, cout << "hello world" calls the non-member overload ostream& operator<<(ostream&, const char*) and this in-turn inserts each character into the output.

Niall
  • 30,036
  • 10
  • 99
  • 142