std::endl 的结构

Structure of std::endl

我是 C++ 的新手,我对 std::endl 感到困惑。在试图理解 std::endl 是什么时,我遇到了一些资源,这些资源告诉我它是一个函数。

可是,函数怎么能去掉括号呢?

阅读 ref:

std::endl

Inserts a new-line character and flushes the stream.

与流一起使用,例如std::cout

这不是一个函数,它是一个函数模板。

不带括号的

std::endl 指的是一组重载函数 - 该函数模板的所有可能特化。在 How does std::endl not use any brackets if it is a function?

中阅读更多内容

endl 是仅输出 I/O 操纵器。

endl is an output-only I/O manipulator, it may be called with an expression such as out << std::endl for any out of type std::basic_ostream.

Inserts a newline character into the output sequence os and flushes it as if by calling os.put(os.widen('\n')) followed by os.flush().

However, how can a function be deprived of parentheses?

函数名后面没有跟(),只是对该函数的引用。它与任何其他类型完全相同:

void foo(int) {}

char x = 'a';

char *p = &x;

int main()
{
  p;  // Refers to p
  *p; // Dereferences p (refers to whatever p points to)
  foo;  // Refers to foo
  foo(42); // Calls foo
}

std::endl 是一个函数(实际上是一个函数模板),它接受一个 "a stream" 类型的参数,并通过将 EOL 表示插入该流然后刷新它来工作。如果您愿意,您实际上可以像使用任何其他函数一样使用它:

std::endl(std::cout);

最后一块拼图是标准库提供了 operator << 的重载(同样是模板),这样 LHS 参数是一个流,RHS 参数是一个函数;此运算符的实现调用 RHS 参数(函数)并将 LHS 参数(流)传递给它。从概念上讲,有这样的东西:

Stream& operator<< (Stream &s, const Function &f)
{
  f(s);
  return s;
}

因此,调用 std::cout << std::endl 会调用该运算符重载,后者又会调用 std::endl(std::cout),后者会执行 EOL 插入 + 刷新。

至于要优先使用哪种形式(直接调用 vs. << 运算符),肯定是使用 <<。它是惯用的, 它允许在单个表达式中轻松组合多个流操纵器。像这样:

std::cout << "Temperature: " << std::fixed << std::setprecision(3) << temperature << " (rounds to " << std::setprecision(1) << temperature << ')' << std::endl;