struct OutputAndConsole : std::ofstream
{
// ...
};
template <typename T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var);
正如其他人提到的,std::endl
是一个模板函数。模板函数不是一个值,这只是一个名字。
如果您尝试将模板函数传递给需要兼容签名的函数,则模板函数可以转换为值。这是not如果传递给模板函数,则转换为值T
or const T&
,因为模板函数的名称代表了一个整体host可能的值。
Because std::endl
不是您自定义编写的有效参数operator<<
,它看起来在别处。它找到了std::ofstream
's operator<<
它通过显式函数指针获取 io 操纵器函数。
那个有效,它可以转换endl
到那个函数指针类型!所以,它高兴地这样称呼它。
要解决此问题,请添加operator<<
过载至OutputAndConsole
它采用 io 操纵器函数指针。
最简单的方法是编写一个辅助函数:
template <class T>
void output_to(OutputAndConsole& strm, const T& var)
{
std::cout << var;
static_cast<std::ofstream&>(strm) << var;
};
然后两个<<
重载:
template<class T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var) {
output_to(strm, var);
return strm;
}
OutputAndConsole& operator<<(OutputAndConsole& strm, std::ostream& (*var)(std::ostream&)) {
output_to(strm, var);
return strm;
}
这导致std::endl
寻找匹配的模板<<
.