5

我的应用程序有不同的部分调用记录器函数来记录详细信息。

记录器类

std::string filename = "blahblah"; // variable to store the location of the properties file 
log4cpp::PropertyConfigurator::configure(filename);

void Logger::logging(const std::string& msg)
{
   Log4cpp::Category& myLogger = log4cpp::Category::getRoot();

   myLogger.log(log4cpp::Priority::INFO, msg);//only takes in string as input
}

调用类

Logger logMe;

int a = 5;
double b = 6;

logMe.logging("log this msg" + a + "," + b);

我意识到上述内容会给我带来错误,因为a它们b是不同类型的。解决它的一种方法是使用std::to_string

logMe.logging("log this msg" + std::to_string(a) + "," + std::to_string(b));

但是,我对日志记录功能有数百次调用,并且每次对std::to_string. 有没有更简单的方法来做到这一点?

哦,澄清一下,代码之前的工作方式是定义#define 函数。

#Define logging(FLAG, X)\
do {\
    ...
    clog << x; \
}while(0)

logging(LogFlag::Warning, "log this msg" << a << "," << b << endl);

但我现在正在重写部分代码以符合静态测试。

提前致谢。

4

3 回答 3

5

您可以添加一个logging带参数包的重载并将其连接到一个字符串中,使用std::stringstream

在 c++17 中,我们可以使用折叠表达式,例如

template <typename Args ...>
void Logger::logging(Args ... args)
{
   std::stringstream ss;
   (ss << ... << args); 

   Log4cpp::Category& myLogger = log4cpp::Category::getRoot();

   myLogger.log(log4cpp::Priority::INFO, ss.str());
}

在 c++11 或 14 中,我们必须稍微复杂一些

template <typename ... Args >
void Logger::logging(Args ... args)
{
   std::stringstream ss;
   std::initializer_list<int> unused{ (ss << args, 0)... };

   Log4cpp::Category& myLogger = log4cpp::Category::getRoot();

   myLogger.log(log4cpp::Priority::INFO, ss.str());
}

然后你打电话给例如

logMe.logging("log this msg", a, ",", b);
于 2017-08-11T08:16:58.343 回答
4

我建议operator<<()在课堂上添加一个

class Logger
{
     public:

          Logger &operator<<(const std::string &s)
          {
              logging(s)
              return *this;
          };

          Logger &operator<<(const char *s)
          {
              return operator<<(std::string(s));
          }


          template <class T>
               Logger &operator<<(const T &v)
          {
               std::ostringstream s;
               s << v;
               return operator<<(logging(ss.str()));
          };

       // other stuff you have in your class, including the logging() function
};

//  to use

logMe << "log this msg" << a << b;

使用它的语法与您描述的不完全相同,但它更普遍。

于 2017-08-11T07:49:12.403 回答
3

使用stringstream. 然后,您可以将其转换为std::string使用str().

#include <sstream>
...
int a = 5;
double b = 6;

std::stringstream ss;
ss << "log this msg" << a << b;
std::cout << ss.str() << std::endl;
logMe.logging(ss.str());
于 2017-08-11T07:31:40.593 回答