Подтвердить что ты не робот

Как std:: endl не использует никаких скобок, если это функция?

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

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

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

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

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

4b9b3361

Ответ 1

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<<), правильная специализация может быть однозначно выведена.

Ответ 2

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

ИЗМЕНИТЬ

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

Ответ 3

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

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