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;
我是 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 typestd::basic_ostream
.Inserts a newline character into the output sequence os and flushes it as if by calling
os.put(os.widen('\n'))
followed byos.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;