且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C++流作为重载operator<<时的参数

更新时间:2023-11-10 19:52:34

endl 是个奇怪的野兽.它不是一个常数值.它实际上是所有事物中的一个函数.你需要一个特殊的覆盖来处理 endl 的应用:

endl is a strange beast. It isn't a constant value. It's actually, of all things, a function. You need a special override to handle the application of endl:

logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
  cout << pf;
  return log;
}

这接受一个函数的插入,该函数接受一个 ostream 引用并返回一个 ostream 引用.这就是 endl 是什么.

This accepts insertion of a function that takes an ostream reference and returns an ostream reference. That's what endl is.

回应 FranticPedantic 的有趣问题为什么编译器不能自动推断出这一点?".原因是,如果你再深入研究,endl 实际上本身就是一个 模板 函数.定义为:

In response to FranticPedantic's interesting question of "why can't the compiler deduce this automatically?". The reason is that if you delve yet deeper, endl is actually itself a template function. It's defined as:

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

也就是说,它可以接受任何类型的ostream 作为它的输入和输出.所以问题不在于编译器无法推断 T const & 可能是一个函数指针,而是它无法确定 哪个 endl 您打算传入.问题中提供的 operator<< 模板化版本将接受指向任何函数的指针作为其第二个参数,但同时,endl 模板表示一个无限潜在函数集,因此编译器在那里不能做任何有意义的事情.

That is, it can take any sort of ostream as its input and output. So the problem isn't that the compiler can't deduce that T const & could be a function pointer, but that it can't figure out which endl you meant to pass in. The templated version of operator<< presented in the question would accept a pointer to any function as its second argument, but at the same time, the endl template represents an infinite set of potential functions, so the compiler can't do anything meaningful there.

提供 operator 的特殊重载,其第二个参数与 endl 模板的特定实例相匹配,允许调用解析.

Providing the special overload of the operator<< whose second argument matches a specific instantiation of the endl template allows the call to resolve.