您的问题与 << 的链无关,单个 log << endl 也会导致问题。这是因为std::endl是一个模板函数:
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
operator<< 在basic_ostream 中的一个重载是:
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;
}
或者你可以在class 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。