Bin Zhou
Bin Zhou

Reputation: 603

How to understand function ostream& operator<< (ostream& os, const unsigned char* s)

For function declaration like

ostream& operator<< (ostream& os, const unsigned char* s);

I am wondering what has been returned. The CPP reference says it returns ostream object. But why it is ostream& instead of simple ostream?

Thank you

Upvotes: 5

Views: 7047

Answers (4)

SirGuy
SirGuy

Reputation: 10770

First reason: std::ostreams are not copyable in general (in C++11 the copy constructor is actually deleted). You don't want to return a copy anyway because chaining wouldn't work:

    std::stringstream s;
    s << "String1" << "String2";

would fail to compile because because the copy returned by the first operator call would not be convertible to the reference required for the second call.
Making both values instead of references also wouldn't work:

    std::stringstream s;
    s << "String1" << "String2";
    assert(s.str() == "String1String2");

Your code will compile but the assert will fail because the object s remains unmodified after these calls because it was passed by copy instead of by reference.

Second reason: all the actual stream objects you will use derive from std::ostream. If this parameter were passed by copy then you get slicing where you effectively lose the object you were using.
This means the following code wouldn't work (if passing by reference but returning by copy- and somehow getting around the compilation error?):

    std::stringstream s;
    s << "String1" << "String2" << std::endl;
    assert(s == "String1String2");

s would only hold "String1" in this case because when you returned the std::stringstream by copy of std::ostream, the returned object is no longer a std::stringstream object and calling operator<< on that passes "String2" into a temporary object which just gets destroyed by the end.

Those are the two important reasons I can think of to return by reference and not by value.

Upvotes: 4

Thomas Russell
Thomas Russell

Reputation: 5980

The reason that the operator returns a ostream& (i.e. a modifiable reference to an ostream object), rather than a copy or void is that it allows for chaining, for instance, a common example with std::cout as the ostream object:

unsigned int i = 2;
std::cout << "This is a test to print " << "some text and maybe some numbers: " << i << std::endl;

Here we chain two const char*s, an unsigned int and a stream modifer, without having to seperate them with separate lines, this makes it nicer to read and understand.

Upvotes: 5

fzhou
fzhou

Reputation: 417

Returning simple objects would require the compiler to generate an object copy but returning references don't.

Upvotes: 1

Alexis
Alexis

Reputation: 2179

Because you return "os" like that you can do a chaining;

std::cout << "string1" << "string2" << std::endl;

Upvotes: 1

Related Questions