Поскольку endl
является шаблоном функции:
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
Таким образом, сам идентификатор не является значением.Он становится значением (указателем на функцию), только когда создается его экземпляр.Но ваш operator<<
сам по себе является шаблоном, и нет никакой информации о типах, доступной для компилятора, чтобы решить, с какими типами создавать экземпляр endl
.1011 *
Следовательно, почему это работает.
endl
работает для basic_ostream
, потому что тот определяет перегрузки operator<<
как функции-члены, принимающие указатели на функции;в частности:
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
Таким образом, при вызове, подобном stream << endl
, он будет знать charT
и traits
из типа this
(то есть с левой стороны оператора), и это даст емуточный тип указателя на функцию, ожидаемый с правой стороны - который он затем использовал бы для создания экземпляра соответствующей версии endl
.Вы можете сделать то же самое для своего класса.