你的问题不在于 <<
连锁反应,一个单独的 log << endl
也会导致问题。问题出在 std::endl
是一个模板函数:
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
basic_ostream
中的operator<<
重载之一是:
template <class charT, class traits = char_traits<charT> >
class basic_ostream : virtual public basic_ios<charT,traits> {
public:
basic_ostream<charT,traits>& operator<<(
basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
};
因此,当使用std::cout<<std::endl
时,模板参数可以被推导出来。然而,当左侧为class Logger
时,编译器无法推导出endl
的模板参数。显式给出模板参数可以让程序编译并工作:
#include <iostream>
class Logger
{
public:
std::ostream &m_file;
Logger(std::ostream &o = std::cout):m_file(o){};
template <typename T>
Logger &operator<<(const T &a) {
m_file<<a;
return *this;
}
};
int main()
{
Logger log;
log<<std::endl<char, std::char_traits<char> >;
log<<"hi"<<" stackoverflow"<<std::endl<char, std::char_traits<char> >;
return 0;
}
或者您可以在Logger
类中添加一个新的重载operator<<
,让编译器推断出std::endl
的模板参数:
#include <iostream>
class Logger
{
public:
std::ostream &m_file;
Logger(std::ostream &o = std::cout):m_file(o){};
template <typename T>
Logger &operator<<(const T &a) {
m_file<<a;
return *this;
}
Logger &operator<<(std::ostream& (*pf) (std::ostream&)){
m_file<<pf;
return *this;
}
};
int main()
{
Logger log;
log<<std::endl;
log<<"hi"<<" stackoverflow"<<std::endl;
return 0;
}
此外,如果您不需要立即刷新输出,可以使用 '\n' 代替
endl
。
endl
。但要注意,如果OP想确保输出缓冲区被刷新,就不能这样做,正如我最近了解到的那样(https://dev59.com/rWsy5IYBdhLWcg3wzBF4)。 - Some programmer dude