ostream chaining, output order
up vote
10
down vote
favorite
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<<?
c++ iostream chaining
add a comment |
up vote
10
down vote
favorite
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<<?
c++ iostream chaining
add a comment |
up vote
10
down vote
favorite
up vote
10
down vote
favorite
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<<?
c++ iostream chaining
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<<?
c++ iostream chaining
c++ iostream chaining
asked Jan 19 '12 at 18:22
LowTechGeek
226112
226112
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
up vote
5
down vote
accepted
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
ostreambut that can also chain withoperator<<?
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!
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain withoperator<<?"
– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
add a comment |
up vote
3
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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
add a comment |
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
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
ostreambut that can also chain withoperator<<?
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!
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain withoperator<<?"
– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
add a comment |
up vote
5
down vote
accepted
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
ostreambut that can also chain withoperator<<?
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!
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain withoperator<<?"
– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
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
ostreambut that can also chain withoperator<<?
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 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
ostreambut that can also chain withoperator<<?
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!
edited Nov 11 at 7:58
answered Jan 19 '12 at 18:32
Nawaz
249k87551748
249k87551748
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain withoperator<<?"
– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
add a comment |
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain withoperator<<?"
– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
1
1
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain with
operator<<?"– Ben Voigt
Jan 19 '12 at 18:55
Doesn't answer "What is the proper way to write a function that inserts data into an ostream but that can also chain with
operator<<?"– Ben Voigt
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
your answers editing complexity seems to be O(Time) :D
– Mr.Anubis
Jan 19 '12 at 18:55
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@Mr.Anubis: I was having dinner in between :P
– Nawaz
Jan 19 '12 at 18:56
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
@BenVoigt: Hope it does now.
– Nawaz
Jan 19 '12 at 19:02
add a comment |
up vote
3
down vote
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.
add a comment |
up vote
3
down vote
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.
add a comment |
up vote
3
down vote
up vote
3
down vote
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.
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.
edited May 23 '17 at 12:32
Community♦
11
11
answered Jan 19 '12 at 18:30
Joachim Isaksson
140k16199238
140k16199238
add a comment |
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
up vote
1
down vote
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.
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.
answered Jan 19 '12 at 18:34
bames53
67.9k6130191
67.9k6130191
add a comment |
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
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.
add a comment |
up vote
1
down vote
up vote
1
down vote
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.
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.
answered Jan 19 '12 at 18:36
Ben Voigt
233k28307563
233k28307563
add a comment |
add a comment |
up vote
1
down vote
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
add a comment |
up vote
1
down vote
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
add a comment |
up vote
1
down vote
up vote
1
down vote
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
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
answered Mar 5 at 12:14
xskxzr
5,75582051
5,75582051
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8931249%2fostream-chaining-output-order%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown