3

In this Stack Overflow answer it says that std::cout << "Hello World!" << std::endl; is the same as

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

But when I compile the above line code, it doesn't compile! Then after trying something else I found that the reason it doesn't compile is because of std::endl, if I replace std::endl by "\n" then it works. But why you can not pass std::endl to std::operator<<?

Or more simply, isn't std::cout<<std::endl; the same as std::operator<<(std::cout, std::endl);?

EDIT

When compile with icpc test.cpp, the error message is error: no instance of overloaded function "std::operator<<" matches the argument list argument types are: (std::ostream, <unknown-type>) std::operator<<(std::cout, std::endl);

and g++ test.cpp gives much much longer error message.

Community
  • 1
  • 1
Allanqunzi
  • 3,230
  • 1
  • 26
  • 58
  • The latter question could likely be answered by just trying *that* line of code. And "...it doesn't compile!" means little unless you also include *the error message* you received when it failed to compile *in your question*. – WhozCraig Jun 30 '15 at 23:36
  • I tried, `std::operator<<(std::cout, std::endl);` does not compile. – Allanqunzi Jun 30 '15 at 23:37
  • 2
    The overload for manipulators is a member function, so `std::cout.operator<<(std::endl)` – David G Jun 30 '15 at 23:51
  • What's the difference of `std::operator <<` and `std::cout.operator <<`? Where do you think I can find a reference to `std::operator <<`? – Allanqunzi Jul 01 '15 at 00:00
  • @Allanqunzi It is a member function call vs a non-member function call. Similar to `print(x, "hi")` vs `x.print("hi")`. [Though operator functions are found differently](http://en.cppreference.com/w/cpp/language/unqualified_lookup#Overloaded_operator) than other names. – David G Jul 01 '15 at 00:05

2 Answers2

5

It's because the answer there is a bit wrong. std::endl is a manipulator function, there is no overload for them in definitions of standalone operator<< of ostream. It is a member function of basic_ostream.

In other word, the presented invocation is wrong. It should be one of the following:

#include <iostream>
int main() {
    std::endl(std::operator<<(std::cout, "Hello World!"));
    std::operator<<(std::cout, "Hello World!").operator<<(std::endl);

    //of course if you pass new line as a supported type it works
    std::operator<<(std::operator<<(std::cout, "Hello World!"), '\n');
    std::operator<<(std::operator<<(std::cout, "Hello World!"), "\n");
    std::operator<<(std::operator<<(std::cout, "Hello World!"), string("\n"));
    return 0;
}

Live examples.

Well, some people do say that stream library does not have the prettiest design in the standard.

luk32
  • 15,812
  • 38
  • 62
  • What surprises me is that the first call works. Where is that defined? As a global operator in std::namespace? And even better: `operator<<(std::cout, "hello, world").operator<<(std::endl)` so that ADL finds the `std::operator`, right? – WorldSEnder Jun 30 '15 at 23:55
  • @5gon12eder Yes, I included working examples as an edit. – luk32 Jun 30 '15 at 23:56
  • @5gon12eder Oh, sure. It's a habit, and the `using` is from copy-pasta from ideone standard template. – luk32 Jul 01 '15 at 00:00
  • Thanks for explaining. One more question what's the difference of the `operator <<` in `ostream` and `std::operator <<`, in the question I asked it is `std::operator <<`, but in your explanation it is the `ostream::operator <<`. – Allanqunzi Jul 01 '15 at 00:06
  • @WorldSEnder I am not sure what you ask about. But I edit the answer to provide links. `operator<<(std::basic_ostream)` is defined in [`ostream`](http://en.cppreference.com/w/cpp/header/ostream), ADL is nicely described in the linked question and answers. – luk32 Jul 01 '15 at 00:07
  • @Allanqunzi They are defined in different places. You can define nearly every operator as a member and a non-member function, but this is more general than just `operator<<`. You can read about it here: http://en.cppreference.com/w/cpp/language/operators . And here: http://stackoverflow.com/a/4421729/1133179 . – luk32 Jul 01 '15 at 00:09
  • I wonder what the reasong behind the design choice not to include the overload for manipulators in the namespace was. – WorldSEnder Jul 01 '15 at 00:10
  • @WorldSEnder I am not sure, maybe it's worth asking on its own, what is the technical reason behind it. I am quite sure there is a good one. – luk32 Jul 01 '15 at 00:21
1

I dont know about this topic, but i think these 2 questions and answers are somewhat related to your question and might help you figure out a solution

operator << must take exactly one argument

Does std::cout have a return value?

Community
  • 1
  • 1
Shivam
  • 457
  • 1
  • 6
  • 15