我正在创建一个小型日志记录类,它允许使用模板函数实现类似 printf 的语法(礼貌 boost::format)来实现可变长度参数列表。我想我已经接近了:在实例化一个 Log 对象“记录器”之后,我希望能够编写logger.Print("This %s is a %s", some_obj, another_obj);
. 按照我目前的方式,这会产生错误“'Log'中没有名为'Print'的成员”。
谁能建议我需要改变什么?
日志.h:
#ifndef LOG_H
#define LOG_H
#include <string>
using std::string;
#include <sstream>
#include <ostream>
#include <fstream>
#include <boost/format.hpp>
enum Severity {
DEBUG,
INFO,
WARN,
CRIT,
DIE,
LEVELS // always last; holds # of severity levels
};
class Log {
public:
Log();
Log(const char*, const char*);
void Print_r(int, const boost::format& );
private:
static const char * sev_code[];
// order is important here!
std::ofstream output_file_stream; // this must be initialized ..
std::ostream& output_stream; // .. before this is bound.
};
int LEVEL; // (where does this belong?)
// This unpacks the variadic arguments one at a time recursively
template <typename T, typename... Params>
void Print_r (int severity, boost::format &boost_format, const T &arg, const Params&... parameters) {
Print_r(severity, boost_format % arg, parameters...); // recursively unpack
}
// This checks severity and converts pat to boost::format
template <typename... Params>
void Print (int severity, const string &pat, const Params&... parameters) {
if (severity < LEVEL) return;
boost::format boost_format(pat);
Print_r(severity, boost_format, parameters...);
}
#endif
日志.cpp:
#include "Log.h"
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <fstream>
const char * Log::sev_code[] = {
"DBUG",
"INFO",
"WARN",
"CRIT",
"DIE "
};
// Constructor w/no parms = logging to cout
Log::Log() :
output_stream(cout) {
}
// Constructor w/parms = logging to file
Log::Log(const char* dir, const char* file) :
output_stream(output_file_stream) {
string output_file_name = string(dir) + "/" + string(file);
output_file_stream.open(output_file_name.c_str(), std::ofstream::out);
}
// This does the actual logging of the formatted message to the
// output_stream:
void
Log::Print_r (int severity, const boost::format &boost_format) {
std::stringstream s;
s << "[" << sev_code[severity] << "] "
<< boost_format;
output_stream << s << endl;
}