Как std :: endl не использует скобки, если это функция? - PullRequest
23 голосов
/ 02 октября 2011

Вопрос в значительной степени в названии. Согласно C ++ Reference , std::endl на самом деле является функцией. Глядя на его объявление в <iostream>, это можно проверить.

Однако, когда вы используете std::endl, вы не используете std::endl(). Вместо этого вы используете:

std::cout << "Foo" << std::endl;

На самом деле, если вы используете std::endl(), компилятор требует больше параметров, как указано по ссылке выше.

Кто-нибудь захочет объяснить это? Что такого особенного в std::endl? Можем ли мы реализовать функции, которые не требуют скобок при вызове?

Ответы [ 3 ]

30 голосов
/ 02 октября 2011

std::endl - это объявленный шаблон функции (27.7.3.8):

template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);

Причина, по которой вы можете "передать" его на std::cout, заключается в том, что шаблон класса basic_ostream имеет членобъявлено:

basic_ostream<charT,traits>& operator<<
    ( basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&) );

, что определено как результат возврата pf(*this) (27.7.3.6.3).

std::endl без скобок относится к набору функций перегрузки -все возможные специализации шаблона функции, но используемые в контексте, где указатель функции одного конкретного типа является приемлемым (то есть в качестве аргумента для operator<<), правильная специализация может быть однозначно выведена.

1 голос
/ 02 октября 2011

Хотя это функция [шаблон], стандартные потоковые манипуляторы предназначены для отправки в потоки в виде указателей на функции (или ссылки на объекты-функции).Вставка результата вызова функции не даст вам ничего, кроме значения , получающегося в результате вызова этой функции.

Это означает, что вы скорее отправляете поток в потоковом виде (f)чем результат его вызова (f()).

0 голосов
/ 02 октября 2011

std::endl - это объект некоторого типа (не очень важный), который предоставляется в качестве аргумента operator<<( std::ostream &, decltype(std::endl)).

EDIT

Чтение другого вопроса привело бы меня к мысли, что endl является шаблоном функции и что мы, скорее всего, выбрали перегрузку функции-члена ostream& operator<<(ostream&(*)(ostream&)).

...