I have a function that takes an ostream
reference as an argument, writes some data to the stream, and then returns a reference to that same stream, like so:
#include <iostream>
std::ostream& print( std::ostream& os ) {
os << " How are you?" << std::endl;
return os;
}
int main() {
std::cout << "Hello, world!" << print( std::cout ) << std::endl;
}
The output of this code is:
How are you?
Hello, world!0x601288
However, if I separate the chaining expressions into two statements, like this
int main() {
std::cout << "Hello, world!";
std::cout << print( std::cout ) << std::endl;
}
then I at least get the proper order in the output, but still get a hex value:
Hello, world! How are you?
0x600ec8
I would like to understand what's going on here. Does a normal function take precedence over operator<<
, and that's why the output order reverses? What is the proper way to write a function that inserts data into an ostream
but that can also chain with operator<<
?
The behavior of your code is unspecified as per the C++ Standard.
Explanation
The following (I removed
std::endl
for simplicity)is equivalent to this:
which is a function call, passing two arguments:
operator<<(std::cout, "Hello, World!")
print(std::cout)
Now, the Standard doesn't specify the order in which arguments are evaluated. It is unspecified. But your compiler seems to evaluate the second argument first, that is why it prints "How are you?" first, evaluating the second argument to a value of type
std::ostream&
which then gets passed to the call shown above (that value is the objectstd::cout
itself).Why hexadecimal output?
You get hexadecimal output because the second argument evaluates to
std::cout
, which is being printed as hexadecimal number, becausestd::cout
implicitly converts into pointer value ofvoid*
type, which is why it is printed as hexadecimal number.Try this:
It will print the same value for both. For example, this example at ideone prints this:
Also note that I didn't use explicit cast; rather
std::cout
is implicitly converted into pointer type.Hope that helps.
When it depends on what you mean by chaining? Obviously, the following wouldn't work (as explained above):
No matter how you write
print()
.However this is well-defined: