C++'s std::cout seems to be an interesting thing. I tried the following program on my C++ compiler today:
cout<<"!"<<"@"<<endl;
cout<<"!"<<cout<<"@"<<endl;
cout<<"!"<<(cout<<"@")<<endl;
And the outputs are rather curious:
!@
!0x601068@
@!0x601068
The first line is pedestrian; the second is understandable; however, the third line is beyond my knowledge. Could someone explain the output? Thank you guys all in advance!
Ziyao Wei
This line:
cout<<"!"<<(cout<<"@")<<endl;
It is first executing:
(cout << "@")
Note: It could have executed something else first, but the compiler optimized this sub-expression and found it could move this to the start of the statement without breaking any constraints.
The result of this expression is a stream (cout). So the resulting expression is:
cout<<"!"<< cout <<endl;
This results in:
@!<pointer>
The parenthes affect the order of evaluation here as in any other expression (<< is an operator). Because the expression has side-effects , those side-effects occur in the same order as the expression evaluation.
This third line illustrates the syntactic sugar that is the insertion operator.
Essentially the (cout<<"@")
expression is evaluated first, resulting in the @
, which returns the stream cout
itself.
Its only then that the !
first, followed by the expression is sent to cout
.
Its equivalent to:
operator<<( operator<<( operator<<(cout,"!"), ( operator<<(cout,"@") ) ), endl);
^------------------^
The highlighted section is an expression which has to be evaluated before any functions are called.
My supposition -- the parentheses in the 3rd line make the cout<<"@"
execute first, which puts the @
at the start of the line. Then the cout.operator<<("!")
executes which puts the !
in place. And then the ostream
that cout.operator<<("!")
returns runs its operator<<()
which is given the ostream
that cout<<"@"
returned, thus outputting the 0x601068
.
If you understand the second line, why does the third confuse you?
First of all, the expression in the parentheses is evaluated (but the order of evaluation is unspecified), thus @
is wrote on the standard output; such expression returns a reference to cout
, as happens always with insertion operators, since otherwise they couldn't be chained.
Now that this part of the expression is evaluated, everything proceeds as normal: what is on the line is wrote from left to right: first the !
, then the value returned from the expression in the parentheses (ie the reference to cout
and then the endl
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.