我想制作一个可以像这样使用的记录器std::cout
,但我想记录一些额外的数据,例如日期,时间,__LINE__
, __func__
, and __FILE__
应该自动保存到文件中。
Example
ToolLogger log;
log << "some data" << std::endl;
预期产出
[14.11.2015 21:10:12.344 (main.cpp) (main,14): some data
解决方案不充分
为此,我必须放置类似的宏__LINE__
直接在我调用记录器的行中,否则宏将无法正常工作。我发现我可以替换std::endl
用我的宏可以像这样实现这个黑魔法:
#define __FILENAME__ (strrchr(__FILE__,'/') ? strrchr(__FILE__,'/') + 1 : __FILE__)
#define logendl \
((ToolLogger::fileName = __FILENAME__).empty() ? "" : "") \
<< ((ToolLogger::line = __LINE__) ? "" : "") \
<< ((ToolLogger::function = __func__).empty() ? "" : "") \
<< std::endl
宏观logendl
使用我的静态变量ToolLogger
类来保存值__LINE__
, __func__
and __FILE__
稍后需要。所以实际使用记录器将如下所示:
ToolLogger log;
log << "some data" << logendl;
在课堂上我必须超载operator<<
为了让它发挥作用,我需要其中两个。一种用于取正常值,例如std::string
or int
,另一个采取std::endl
操纵器。以下是我的课堂上最重要的事情:
class ToolLogger
{
public:
// standard operator<< //
template<typename T>
ToolLogger& operator<< (const T& str)
{
out << str;
return *this;
}
// operator<< for taking the std::endl manipulator //
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
typedef CoutType& (*StandardEndLine)(CoutType&);
ToolLogger& operator<<(StandardEndLine manip)
{
// save fileName, line and function to the file //
// and all what is already in stringstream //
// clear stringstream //
return *this;
}
static string fileName;
static int line;
static string function;
private:
ofstream file;
std::stringstream out;
};
string ToolLogger::fileName;
int ToolLogger::line;
string ToolLogger::function;
Problem
该解决方案的问题是我可以通过两种方式使用记录器:
log << "some data" << logendl; // correct //
log << "some data" << std::endl; // compiles -> wrong /
所以实际上我需要删除operator<<
从我的课上std::endl
操纵器,还有其他办法解决,但是怎么办呢?我正在考虑改变std::endl
in logendl
宏到其他自定义操纵器,然后这个自定义操纵器将执行实际正在执行的工作operator<<
,但我不知道该怎么做。我正在寻找其他解决方案,有什么建议吗?