There is nothing really special about this. std::ostream::operator<< is simply overloaded to accept various types in input.
In the case of manipulator functions, operator<< is overloaded to accept certain types of function pointers as input by default:
basic_ostream& operator<<(
std::ios_base& (*func)(std::ios_base&) );
basic_ostream& operator<<(
std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) );
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
And then the implementations of those overloads just call whatever function is passed in to them, specifying *this as the function's input parameter, eg:
basic_ostream& basic_ostream::operator<<(std::ios_base& (*func)(std::ios_base&) )
{
(*func)(*this);
return *this;
}
basic_ostream& basic_ostream::operator<<(std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&))
{
(*func)(*this);
return *this;
}
basic_ostream& basic_ostream::operator<<(std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&))
{
(*func)(*this);
return *this;
}
Thus cout << std::endl; is simply calling cout.operator<<(std:endl);, where std::endl() matches the 3rd overload above:
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );
In the case of the stream manipulator functions in the <iomanip> header, the manipulators that do not take any input parameters from user's code (ie std::boolalpha, std::showbase, etc) are usually implemented as standalone functions that match one of the overloads above, and thus DO get passed the ostream/istream directly as a parameter. However, the manipulators that take input parameters from user code (ie std::resetiosflags(), std::setbase(), etc) are defined to return "unspecified" (ie implementation-defined) types, where their implementations define additional overloads of operator<< and operator>> for those types so they can receive the ostream/istream to manipulate, respectively.
For example: std::fill might be implemented something like this:
template< class CharT >
struct fill_t { CharT ch; };
template< class CharT >
fill_t setfill( CharT c )
{
return fill_t<CharT>{c};
}
template< class CharT >
basic_ostream& operator<<(basic_ostream& out, const fill_t &in)
{
out.fill(in.ch);
return out;
}
Thus cout << setfill(' ') calls the equivalent of fill_t tmp = setfill(' '); operator<<(cout, tmp);