LOG4CXX_INFO不是#define的干净包装器

我正在尝试将C ++中的#define宏包装到内联或模板函数中。在LOG4CXX中,它具有如下定义:

#define LOG4CXX_INFO(logger,message) { \
        if (logger->isInfoEnabled()) {\
           ::log4cxx::helpers::MessageBuffer oss_; \
           logger->forcedLog(::log4cxx::Level::getInfo(),oss_.str(oss_ << message),LOG4CXX_LOCATION); }}

我需要在日志中添加其他上下文,并将LOG4CXX_INFO包装在另一个定义中,并使此实现起作用。我想摆脱使用#define来包装它并以更C ++的方式进行操作。我遇到的这个问题是,消息参数可以使用+或

如果我尝试将其模板化,例如:

   template<typename T> 
   void info(LoggerPtr logger,const T& message) {
        ...do stuff ...
        LOG4CXX_INFO(logger,message);
   }

编译器会抱怨找不到各种类型对象的

要完成这项工作需要做什么?

在ubuntu上与以下内容一起编译

gcc main.cpp -lstdc++ -llog4cxx
#include <log4cxx/logger.h>

using namespace std;

#define info(logger,message) LOG4CXX_INFO(logger,message)

template<typename T> void tinfo(log4cxx::LoggerPtr logger,const T& message) {
     LOG4CXX_INFO(logger,message);
}

int main()
{
        log4cxx::LoggerPtr logger;
        LOG4CXX_INFO(logger,"test" << "test2");

        info(logger,"another test");
        info(logger,"another test" << "another test2");

        tinfo(logger,"test template");

        //tinfo(logger,"test template" << "test template 2"); -> this line does not compile
        return 0;
}

编译器错误:

main.cpp: In function ‘int main()’:
main.cpp:21:31: error: invalid operands of types ‘const char [14]’ and ‘const char [16]’ to binary ‘operator<<’
  tinfo(logger,"test template" << "test template 2");

MessageBuffer代码可在以下位置找到:https://github.com/apache/logging-log4cxx/blob/master/src/main/include/log4cxx/helpers/messagebuffer.h和此处https://github.com/apache/logging-log4cxx/blob/master/src/main/cpp/messagebuffer.cpp

liutongyanjss 回答:LOG4CXX_INFO不是#define的干净包装器

tinfo(logger,"test template" << "test template 2");

是错误的。它先 "test template" << "test template 2",然后将结果传递给函数。但这没有任何意义,因为<<的左侧应该是一个流对象。

这适用于宏,因为宏是纯文本替换,所以替换

LOG4CXX_INFO(logger,"test" << "test2");

收益

oss_ << "test" << "test2"

,从左到右评估。 如果在宏参数周​​围加上括号

LOG4CXX_INFO(logger,("test" << "test2"));

您忠实地重现了函数的行为,由于要进行评估,您将得到相同的错误

oss_ << ("test" << "test2")

如果要在一个函数调用中输出多个内容,建议使用fold表达式(自C ++ 17起可用):

template<typename... Ts>
void tinfo(log4cxx::LoggerPtr logger,const Ts&... messages) {
    if (logger->isInfoEnabled()) {
        ::log4cxx::helpers::MessageBuffer oss_; 
        logger->forcedLog(::log4cxx::Level::getInfo(),oss_.str((oss_ << ... << messages)),LOG4CXX_LOCATION);
    }
}

tinfo(logger,"test template","test template 2");

如果您想保留原始语法和/或引用LOG4CXX_INFO而不是重新实现该宏的主体,那么我认为没有宏是不可能的。

本文链接:https://www.f2er.com/3098651.html

大家都在问