Это путь потоковые манипуляторы работают. Манипуляторы - это функции, переданные оператору < < в качестве аргументов. Тогда внутри оператора они просто вызываются.
Так у вас есть функция, объявленная как
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
и вы передаете свой указатель на оператор < <. А внутри оператора, объявленной что-то вроде
ostream& ostream::operator << (ostream& (*op)(ostream&));
функция called.like
return (*endl)(*this);
Таким образом, когда вы видите рекорд
std::cout << std::endl;
затем std::endl
является указатель на функцию, которая передается в operator <<
как аргумент.
В записи
std::endl(std::cout);
префикс пространства имен перед именем endl
может быть опущен, так как в этом случае компилятор будет использовать аргумент Dependent Lookup. Таким образом, эта запись
endl(std::cout);
скомпилируется успешно.
Однако если заключите имя функции в скобках, то ADL не используется и следующая запись
(endl)(std::cout);
не будет скомпилирован.
Похоже на [Интересное поведение компилятора с пространствами имен] (http://stackoverflow.com/q/25976267/1708801) –