C++ 超载<&书信电报;运算符并将参数传递到std::cout
我想创建一个用于日志记录的类,其行为类似于C++ 超载<&书信电报;运算符并将参数传递到std::cout,c++,templates,c++11,stdout,ostream,C++,Templates,C++11,Stdout,Ostream,我想创建一个用于日志记录的类,其行为类似于std::cout,但会自动向流中插入附加信息 我想要的示例用法如下(现在不必关心对象和上下文类型,只需假设它们是std::string): 我一直在尝试: template<typename T> Logger& operator << (const T& msg){ std::cout << timestamp() << msg << std::endl <&l
std::cout
,但会自动向流中插入附加信息
我想要的示例用法如下(现在不必关心对象和上下文类型,只需假设它们是std::string):
我一直在尝试:
template<typename T>
Logger& operator << (const T& msg){
std::cout << timestamp() << msg << std::endl << std::flush;
return *this;
}
模板
Logger&operator您的代码不起作用的原因是您没有实现operator如果您愿意,您当然可以重载流类,只要operatorstd::endl
已经刷新流。请参阅:请提供整个(精简但完整)代码以进行复制。然后,不要解释错误,也要引用它。很可能您正在临时或常量记录器上使用它,或者尝试将重载函数(如std::endl
)流式传输到其中,但是如果没有实际的代码和错误,这是不可能的。Loki,这几乎解决了我的问题,谢谢!
[timestamp] Event with object : [obj_desc] while in context : [this context][eol][flush]
template<typename T>
Logger& operator << (const T& msg){
std::cout << timestamp() << msg << std::endl << std::flush;
return *this;
}
Logger l;
l << "Event with object : " << obj << " while in context : " << context;
Logger l;
l.operator<<("Event with object : ").operator<<(obj).operaator<<(" while in context : ").operator<<(context);
struct LoggerStream
{
std::ostringstream strm;
struct Timestamp
{
};
~LoggerStream()
{
std::string s = strm.str();
if (!s.empty())
std::cout << s << std::flush;
}
LoggerStream& operator<< (const Timestamp &t)
{
strm << "[timestamp] "; // format this however you need
return *this;
}
LoggerStream& operator<< (const object &obj)
{
strm << "[obj_desc]"; // format this however you need
return *this;
}
LoggerStream& operator<< (const context &ctx)
{
strm << "[this context]"; // format this however you need
return *this;
}
LoggerStream& operator<< (std::ostream&(*f)(std::ostream&))
{
if (f == (std::basic_ostream<char>& (*)(std::basic_ostream<char>&)) &std::flush)
{
std::string s = strm.str();
if (!s.empty())
std::cout << s << std::flush;
strm.str("");
strm.clear();
}
else
strm << f;
return *this;
}
template<typename T>
LoggerStream& operator<< (const T& value)
{
strm << value;
return *this;
}
};
class Logger
{
LoggerStream getStream()
{
LoggerStream strm;
strm << Timestamp;
return strm;
}
};
Logger l;
l.getStream() << "Event with object : " << obj << " while in context : " << context;
...
l.getStream() << "Event with object : " << obj << " while in context : " << context;
...
Logger l;
LoggerStream strm = l.getStream();
strm << "Event with object : " << obj << " while in context : " << context << std::flush;
...
strm << Logger::Timestamp << "Event with object : " << obj << " while in context : " << context << std::flush;
...
struct Logger
{
std::ostringstream strm;
~Logger()
{
std::string s = strm.str();
if (!s.empty())
std::cout << "[timestamp] " << s << std::flush;
}
Logger& operator<< (const object &obj)
{
strm << "[obj_desc]"; // format this however you need
return *this;
}
Logger& operator<< (const context &ctx)
{
strm << "[this context]"; // format this however you need
return *this;
}
Logger& operator<< (std::ostream&(*f)(std::ostream&))
{
if (f == (std::basic_ostream<char>& (*)(std::basic_ostream<char>&)) &std::flush)
{
std::string s = strm.str();
if (!s.empty())
std::cout << "[timestamp] " << s << std::flush;
strm.str("");
strm.clear();
}
else
strm << f;
return *this;
}
template<typename T>
Logger& operator<< (const T& value)
{
strm << value;
return *this;
}
};
Logger() << "Event with object : " << obj << " while in context : " << context;
...
Logger() << "Event with object : " << obj << " while in context : " << context;
...
Logger l;
l << "Event with object : " << obj << " while in context : " << context << std::flush;
...
l << "Event with object : " << obj << " while in context : " << context << std::flush;
...
#include <iostream>
#include <iomanip>
#include <sstream>
#include <ctime>
#include <unistd.h>
#define logcout std::cout << timestamp()
std::string timestamp(void) {
time_t now = time(0);
struct tm *tmx = localtime(&now);
std::ostringstream oss;
oss << '['
<< (tmx->tm_year+1900)
<< '-'
<< std::setfill('0') << std::setw(2) << (tmx->tm_mon+1)
<< '-'
<< std::setfill('0') << std::setw(2) << (tmx->tm_mday)
<< ' '
<< std::setfill('0') << std::setw(2) << (tmx->tm_hour)
<< ':'
<< std::setfill('0') << std::setw(2) << (tmx->tm_min)
<< ':'
<< std::setfill('0') << std::setw(2) << (tmx->tm_sec)
<< "] ";
return oss.str();
}
int main (int argc, char *argv[]) {
logcout << "A slightly\n";
sleep (5);
logcout << "sneaky" << " solution\n";
return 0;
}
[2015-05-26 13:37:04] A slightly
[2015-05-26 13:37:09] sneaky solution
#define logcout std::cout << timestamp()