我有简单的日志记录类,如下所示。
#include <iostream>
#include <string>
using namespace std;
class log
{
public:
log(){};
~log(){};
log & operator << ( int x ){ cout << x; return * this;}
log & operator << ( string x ){ cout << x; return * this;}
log & operator << ( log & (log::*pf)() ){ (this->*pf)(); return * this;}
log & end( ) { cout << "\r\n"; return * this;}
};
log l;
#define end &log::end;
#define error( z ) l << "ERROR " z << end;
#define warn( z ) l << "WARN " z << end;
int main()
{
int y = 20;
error ( << y );
}
有没有什么方法可以像这样编写我的代码?
error << y;
这里的基本想法是避免用户使用宏 结束
即。我不希望用户像下面那样编码
error << y << end;
答案 0 :(得分:1)
看起来你正在重新发明方形轮给我!实际上,那里有很多记录器库(boost.log是一个很好的)。另一种解决方案是让用户编写标准语法,包括对std::endl
:
error << x << std::endl;
warn << y << std::endl;
您可以通过将字符串"warn"
或"error"
传递给班级log
的指导者来实现。
您必须按Overload handling of std::endl?。
std::endl
参数
答案 1 :(得分:0)
怎么样:
#define LOG(Msg) do { l << Msg << ::std::endl; } while(0)
Log("Hello" << "World");
注意:我在调试版本中使用这样的宏,并在发布版本中使它((void)0)。
对于常见的日志记录,您不应使用宏,并且可以考虑流操纵器。
答案 2 :(得分:0)
一个选项是删除你的全局变量,并使用析构函数通过让宏创建一个范围来编写换行符,以便销毁对象:
#define error( z ) {log l; l << "ERROR " z; }
#define warn( z ) {log l; l << "WARN " z; }
如果没有你的结束宏,这将产生接近你想要的代码:
int y = 20, z = 40;
error ( << y << " " << z);
如果您喜欢这种方法,您可能需要考虑改进宏,以便在宏本身中强制执行日志级别,因此如果该级别的性能对您很重要,则不会使用无关的每条日志消息创建对象。
在这里的任何地方都看不到用于POCO记录的插件,这就是我使用的插件。不是说这对你有用,这正是我喜欢的特殊需求。
答案 3 :(得分:0)
您可以创建课程:
class PrefixLog
{
public:
explicit PrefixLog(const char* prefix) : prefix(prefix) {}
template <typename T>
log& operator << (const T& t) const { return l << prefix << t << &log::end; }
private:
const char* prefix;
};
PrefixLog error("ERROR ");
PrefixLog warning("WARN ");
然后
warning << y;
error << y;