如果它是一个函数,std :: endl如何不使用任何括号?

时间:2011-10-02 00:09:29

标签: c++ visual-studio-2010 std

问题几乎在标题中。根据{{​​3}},std::endl实际上是一个函数。查看<iostream>中的声明,可以进行验证。

但是,当您使用std::endl时,不使用std::endl()。相反,您使用:

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

事实上,如果您使用std::endl(),编译器需要更多参数,如上面的链接所示。

有人会解释这个吗? std::endl有什么特别之处?我们可以在调用时实现不需要任何括号的函数吗?

3 个答案:

答案 0 :(得分:28)

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引用一组重载函数 - 函数模板的所有可能的特化,但在一个特定类型的函数指针可接受的上下文中使用(即作为{{1的参数) }},可以明确推断出正确的专业化。

答案 1 :(得分:1)

std::endl是某种类型的对象(不是很重要),它作为operator<<( std::ostream &, decltype(std::endl))的参数提供。

修改

阅读其他问题会让我认为endl是一个函数模板,我们很可能选择ostream& operator<<(ostream&(*)(ostream&))成员函数重载。

答案 2 :(得分:1)

虽然它是一个函数[template],但标准的流操作符被设计为作为函数指针(或函子对象引用)发送到流。插入函数调用的结果除了由函数调用产生的之外,不会给你任何东西。

这意味着你流式仿函数本身(f),而不是调用它的结果(f())。