Overloaded chained operator<< buffering output [duplicate] - c++

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)
std::cout << "Hello, world!" << print( std::cout );
is equivalent to this:
operator<<(operator<<(std::cout, "Hello, World!"), print(std::cout));
which is a function call, passing two arguments:
First argument is : operator<<(std::cout, "Hello, World!")
Second argument is : 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 object std::cout itself).
Why hexadecimal output?
You get hexadecimal output because the second argument evaluates to std::cout, which is being printed as hexadecimal number, because std::cout implicitly converts into pointer value of void* type, which is why it is printed as hexadecimal number.
Try this:
void const *pointer = std::cout; //implicitly converts into pointer type!
std::cout << std::cout << std::endl;
std::cout << pointer << std::endl;
It will print the same value for both. For example, this example at ideone prints this:
0x804a044
0x804a044
Also note that I didn't use explicit cast; rather std::cout is implicitly converted into pointer type.
Hope that helps.
What is the proper way to write a function that inserts data into an ostream but that can also chain with operator<<?
When it depends on what you mean by chaining? Obviously, the following wouldn't work (as explained above):
std::cout << X << print(std::cout) << Y << Z; //unspecified behaviour!
No matter how you write print().
However this is well-defined:
print(std::cout) << X << Y << Z; //well-defined behaviour!

The reason is that your print() function will be evaluated before the rest of the statement and return a reference to cout which is then actually printed as a pointer (cout << cout). This order of evaluation is actually unspecified behavior, but seems to be the case with your compiler.
As for defining a stream aware "function" that actually has defined behavior with the same functionality, this would work;
#include <iostream>
template <class charT, class traits>
std::basic_ostream<charT,traits>& print ( std::basic_ostream<charT,traits>& os )
{
os << " How are you?" << std::endl;
return os;
}
int main() {
std::cout << "Hello, world!" << print << std::endl;
}
See also this answer for a little more detail on what "unspecified" actually means in this case.

Hexadecimal Output
Before C++11, the class std::ostream has a conversion function to void*. Since your print function returns std::ostream&, when evaluating std::cout << print(...), the returned std::ostream lvalue will be implicitly converted to void* and then be outputted as a pointer value. This is why there is a hexadecimal output.
Since C++11, this conversion function is replaced by an explicit conversion function to bool, so trying to output an std::ostream object becomes ill-formed.
Evaluation Order
Before C++17, overloaded operator is considered a function call for analyzing evaluation order, and evaluation order of different arguments of a function call is unspecified. So it is not strange that the print function is evaluated firstly, which causes How are you? is outputted firstly.
Since C++17, the evaluation order of operands of operator << is strictly from left to right, and operands of overloaded operator share the same evaluation order as those of the bulit-in one (see more details here). So your program will always get the output (assume print returns something able to be outputted)
Hello, world! How are you?
something returned by print
LIVE EXAMPLE

In your statement std::cout << "Hello, world!" << print( std::cout ) << std::endl it's undefined whether std::cout << "Hello, world!" happens before or after print( std::cout ). That's why the order may not be what you expect.
The hex value comes from the fact that you're also doing std::cout << std::cout (print returns std::cout which is fed into the << chain). The right hand std::cout is converted to a void * and that's printed to the output.

This would work, to combine print with << and control the order:
print( std::cout << "Hello, world!" ) << std::endl;
Or, if you want a function that's called with <<, see Joachim's answer.

Related

Why does + operator between string and int acts as substr

When trying to concatenate a string with an int (without using the std::to_string, just to see what happens), I saw that there was no compilation error but the actual result is quite strange.
I tried to search on cplusplus.com how the + operator is defined for string, but I couldn't find any definition of this operator between string and int.
The code used to test the concatenation is the following :
std::cout << "Test" + 3 << std::endl;
I was expecting a compilation error, but I simply got a t in the console, which surprised me a bit.
Why does this operator acts this way, and where is it defined?
Thank you for your answers.
You are not using string+ int, you are doing const char* + int, that's pointer arithmetics.
That's a pointer to "Test", you increment it by 3, which means the pointer points to the substring "t".
As already answered you have pointer arithmetic due to using string literal
To see what happens when you use std::string you need to either cast explicitly:
std::cout << std::string("Test") + 3 << std::endl;
or if you have C++14 or later to use operator ""s
using namespace std::string_literals;
std::cout << "Test"s + 3 << std::endl;
operator+ has a higher precedence than operator<<, so this statement:
std::cout << "Test" + 3 << std::endl;
Get treated by the compiler as if you had written this instead:
std::cout << ("Test" + 3) << std::endl;
"Test" is a string literal of type const char[5], which will decay into a pointer to the T character. So, adding +3 to "Test" performs pointer arithmetic, thus a const char* pointer that is pointing at the t character gets passed to operator<<, as if you had written code like this instead:
const char *ptr = "Test";
ptr = ptr + 3;
std::cout << ptr << std::endl;
Changing "Test" to a std::string won't work by default, either:
std::cout << std::string("Test") + 3 << std::endl;
Because there is no standard operator+ that allows an int to be added to a std::string (you would have to define your custom operator if you want that).
So, to fix this, you have two choices:
Convert the int to a std::string:
std::cout << "Test" + std::to_string(3) << std::endl;
use operator<< instead of operator+:
std::cout << "Test" << 3 << std::endl;

why return reference to ostream object in member function for serialization [duplicate]

This question already has answers here:
Why we need to return reference to istream/ostream while overloading >> and << operators?
(4 answers)
Closed 5 years ago.
//using namespace std;
Here's the following piece of code
ostream& write(ostream& os) const {
os << getRe() << "j " << getIm();
return os;
}
This is a member function in a class representing complex numbers ("PComplex), which is derived from an abstract class ("Serializable"). (Implementation of pure virtual function).
My main question is why do we need to return a reference to an ostream object? Why not void?
Returning an ostream& object allows us to chain a bunch of operators togeather.
Consider this statement
cout << "Hello " << "World";
This is actually two calls to ostream& operator<<(ostream& os, const char* c). If we consider the order of execution, we get:
(cout << "Hello ") << "World";
This function accepts cout on the left and "Hello " on the right. It prints the contents of the right hand-side to the console, then it returns cout. We we consider what's left after the first step we get this:
(cout) << "World";
Now we take the brackets away and get:
cout << "World;
This one is much easier to deal with. Now we call the function again to print `"World" and return the cout again, which we will simply not do anything with.
If we returned void instead of ostream&, then (cout << "Hello ") would reduce to (void). That would leave us with:
(void) << "World";
This doesn't match any overloads and so we would then get an error. While the (cout << "Hello ") would still work, we wouldn't be able to chain << "World" on the same line.

Value of global variable: Output of a C++ program [duplicate]

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)
std::cout << "Hello, world!" << print( std::cout );
is equivalent to this:
operator<<(operator<<(std::cout, "Hello, World!"), print(std::cout));
which is a function call, passing two arguments:
First argument is : operator<<(std::cout, "Hello, World!")
Second argument is : 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 object std::cout itself).
Why hexadecimal output?
You get hexadecimal output because the second argument evaluates to std::cout, which is being printed as hexadecimal number, because std::cout implicitly converts into pointer value of void* type, which is why it is printed as hexadecimal number.
Try this:
void const *pointer = std::cout; //implicitly converts into pointer type!
std::cout << std::cout << std::endl;
std::cout << pointer << std::endl;
It will print the same value for both. For example, this example at ideone prints this:
0x804a044
0x804a044
Also note that I didn't use explicit cast; rather std::cout is implicitly converted into pointer type.
Hope that helps.
What is the proper way to write a function that inserts data into an ostream but that can also chain with operator<<?
When it depends on what you mean by chaining? Obviously, the following wouldn't work (as explained above):
std::cout << X << print(std::cout) << Y << Z; //unspecified behaviour!
No matter how you write print().
However this is well-defined:
print(std::cout) << X << Y << Z; //well-defined behaviour!
The reason is that your print() function will be evaluated before the rest of the statement and return a reference to cout which is then actually printed as a pointer (cout << cout). This order of evaluation is actually unspecified behavior, but seems to be the case with your compiler.
As for defining a stream aware "function" that actually has defined behavior with the same functionality, this would work;
#include <iostream>
template <class charT, class traits>
std::basic_ostream<charT,traits>& print ( std::basic_ostream<charT,traits>& os )
{
os << " How are you?" << std::endl;
return os;
}
int main() {
std::cout << "Hello, world!" << print << std::endl;
}
See also this answer for a little more detail on what "unspecified" actually means in this case.
Hexadecimal Output
Before C++11, the class std::ostream has a conversion function to void*. Since your print function returns std::ostream&, when evaluating std::cout << print(...), the returned std::ostream lvalue will be implicitly converted to void* and then be outputted as a pointer value. This is why there is a hexadecimal output.
Since C++11, this conversion function is replaced by an explicit conversion function to bool, so trying to output an std::ostream object becomes ill-formed.
Evaluation Order
Before C++17, overloaded operator is considered a function call for analyzing evaluation order, and evaluation order of different arguments of a function call is unspecified. So it is not strange that the print function is evaluated firstly, which causes How are you? is outputted firstly.
Since C++17, the evaluation order of operands of operator << is strictly from left to right, and operands of overloaded operator share the same evaluation order as those of the bulit-in one (see more details here). So your program will always get the output (assume print returns something able to be outputted)
Hello, world! How are you?
something returned by print
LIVE EXAMPLE
In your statement std::cout << "Hello, world!" << print( std::cout ) << std::endl it's undefined whether std::cout << "Hello, world!" happens before or after print( std::cout ). That's why the order may not be what you expect.
The hex value comes from the fact that you're also doing std::cout << std::cout (print returns std::cout which is fed into the << chain). The right hand std::cout is converted to a void * and that's printed to the output.
This would work, to combine print with << and control the order:
print( std::cout << "Hello, world!" ) << std::endl;
Or, if you want a function that's called with <<, see Joachim's answer.

Cout and Hex [C++] [duplicate]

This question already has answers here:
Does std::cout have a return value?
(3 answers)
Closed 8 years ago.
Why when you write std::cout twice it shows the hexadecimal value and then what you wanted to output?
E.g.
std::cout << std::cout << "Hello!";
std::cout has a type std::ostream (or something derived from
it). There is no << which takes this type on the right, so
the compiler looks for a conversion. In pre-C++11,
std::ostream converts implicitly to void* (for use in
conditionals), so the compiler uses this; what you're seeing is
the output of what the conversion operator returns (typically,
the address of the std::ostream object itself, but all that is
required is that it be a non-null pointer).
std::ostream has a conversion operator that allows conversion to void* so you can test if operation was successful. In expression
std::cout << std::cout // similar to
// std::cout.operator<<( std::cout.operator void*())
the right-hand operand expression std::cout is implicitly converted to void const* using this conversion operator and then the operator<< does the output of this via the ostream operand . Another way to see this is:
const void* cp = std::cout.operator void*();
std::cout << cp << "Hello!" << std::endl;
std::cout << std::cout << "Hello!";
output:
0x601088Hello!
0x601088Hello!

ostream chaining, output order

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)
std::cout << "Hello, world!" << print( std::cout );
is equivalent to this:
operator<<(operator<<(std::cout, "Hello, World!"), print(std::cout));
which is a function call, passing two arguments:
First argument is : operator<<(std::cout, "Hello, World!")
Second argument is : 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 object std::cout itself).
Why hexadecimal output?
You get hexadecimal output because the second argument evaluates to std::cout, which is being printed as hexadecimal number, because std::cout implicitly converts into pointer value of void* type, which is why it is printed as hexadecimal number.
Try this:
void const *pointer = std::cout; //implicitly converts into pointer type!
std::cout << std::cout << std::endl;
std::cout << pointer << std::endl;
It will print the same value for both. For example, this example at ideone prints this:
0x804a044
0x804a044
Also note that I didn't use explicit cast; rather std::cout is implicitly converted into pointer type.
Hope that helps.
What is the proper way to write a function that inserts data into an ostream but that can also chain with operator<<?
When it depends on what you mean by chaining? Obviously, the following wouldn't work (as explained above):
std::cout << X << print(std::cout) << Y << Z; //unspecified behaviour!
No matter how you write print().
However this is well-defined:
print(std::cout) << X << Y << Z; //well-defined behaviour!
The reason is that your print() function will be evaluated before the rest of the statement and return a reference to cout which is then actually printed as a pointer (cout << cout). This order of evaluation is actually unspecified behavior, but seems to be the case with your compiler.
As for defining a stream aware "function" that actually has defined behavior with the same functionality, this would work;
#include <iostream>
template <class charT, class traits>
std::basic_ostream<charT,traits>& print ( std::basic_ostream<charT,traits>& os )
{
os << " How are you?" << std::endl;
return os;
}
int main() {
std::cout << "Hello, world!" << print << std::endl;
}
See also this answer for a little more detail on what "unspecified" actually means in this case.
Hexadecimal Output
Before C++11, the class std::ostream has a conversion function to void*. Since your print function returns std::ostream&, when evaluating std::cout << print(...), the returned std::ostream lvalue will be implicitly converted to void* and then be outputted as a pointer value. This is why there is a hexadecimal output.
Since C++11, this conversion function is replaced by an explicit conversion function to bool, so trying to output an std::ostream object becomes ill-formed.
Evaluation Order
Before C++17, overloaded operator is considered a function call for analyzing evaluation order, and evaluation order of different arguments of a function call is unspecified. So it is not strange that the print function is evaluated firstly, which causes How are you? is outputted firstly.
Since C++17, the evaluation order of operands of operator << is strictly from left to right, and operands of overloaded operator share the same evaluation order as those of the bulit-in one (see more details here). So your program will always get the output (assume print returns something able to be outputted)
Hello, world! How are you?
something returned by print
LIVE EXAMPLE
In your statement std::cout << "Hello, world!" << print( std::cout ) << std::endl it's undefined whether std::cout << "Hello, world!" happens before or after print( std::cout ). That's why the order may not be what you expect.
The hex value comes from the fact that you're also doing std::cout << std::cout (print returns std::cout which is fed into the << chain). The right hand std::cout is converted to a void * and that's printed to the output.
This would work, to combine print with << and control the order:
print( std::cout << "Hello, world!" ) << std::endl;
Or, if you want a function that's called with <<, see Joachim's answer.