It is well known that the user can define stream manipulators like this:
ostream& tab(ostream & output)
{
return output<< '\t';
}
And this can be used in main() like this:
cout<<'a'<<tab<<'b'<<'c'<<endl;
Please explain me how does this all work? If operator<< assumes as a second parameter a pointer to the function that takes and returns ostream &, then please explain my why it is necessary? What would be wrong if the function does not take and return ostream & but it was void instead of ostream &?
Also it is interesting why “dec”, “hex” manipulators take effect until I don’t change between them, but user defined manipulators should be always used in order to take effect for each streaming?
The standard defines the following operator<<
overload in the basic_ostream
class template:
basic_ostream<charT,traits>& operator<<(
basic_ostream<charT,traits>& (*pf) (basic_ostream<charT,traits>&) );
Effects: None. Does not behave as a formatted output function (as described in 27.6.2.5.1).
Returns:
pf(*this)
.
The parameter is a pointer to a function taking and returning a reference to a std::ostream
.
This means that you can "stream" a function with this signature to an ostream
object and it has the effect of calling that function on the stream. If you use the name of a function in an expression then it is (usually) converted to a pointer to that function.
std::hex
is an std::ios_base
manipulator defined as follows.
ios_base& hex(ios_base& str);
Effects: Calls
str.setf(ios_base::hex, ios_base::basefield)
.Returns: str.
This means that streaming hex
to an ostream
will set the output base formatting flags to output numbers in hexadecimal. The manipulator doesn't output anything itself.