Keep in mind that although iostreams overload <<
(and >>
) to do I/O, these were originally defined as bit-shift operators. When the compiler's parsing the expression, it's basically seeing "operand, operator, operand", then checking whether the operands are of types to which that operator can be applied.
In this case, we have a string literal and (apparently) some sort of integer, and the compiler knows how to do math on those (after converting the string literal to a pointer).
From the compiler's viewpoint, however, this isn't a whole lot different from something like:
int a, b=1, c=2, d = 3;
a = b << c + d;
The difference is that with operands of type int
, the meaning is fairly obvious: it's doing addition and bit-shifting. With iostreams, the meaning attached to <<
and >>
change, but the syntax allowed for them in an expression is unchanged.
From the compiler's "viewpoint" the only question is whether the operands to +
are of types for which +
is allowed--in this case, you have pointer to char + integer
, so that's allowed. The result is a pointer to char, and it has an overload of <<
that takes a left-hand operand of type ostream and a right-hand operator of type pointer to char
, so the expression as a whole is fine (as far as it cares).