是否有可能创建一个C++类来模仿std :: cout语法:通过链接重载插入操作符来执行与easylogging ++相同的方式?

问题描述:

的easylogging ++代码定义一个宏,使得它非常简单易用:是否有可能创建一个C++类来模仿std :: cout语法:通过链接重载插入操作符来执行与easylogging ++相同的方式?

LOG(logLevel) << "This mimics std::cout syntax. " << 1 << " + " << 1 << " = " << 2; 

我想打一个包装类easylogging ++。我可以使用两个参数轻松创建一个函数来包装上面的行。但是,是否有可能在包装类中模仿这种语法?例如:

Logger logger; 
logger(logLevel) << "Line " << 1 << " of log text."; 

我知道我可以很容易地重载插入运算符,但仍然给我留下了无需编写另一个函数以每次设置日志级别。

UPDATE:

由于Starl1ght的回答,我能够得到这个工作。我想我会分享以防其他人有类似的需求。

我创建了两个重载。一个用于(),另一个用于< <。

Logger &operator()(logLevelT logLevel) { 
    mLogLevel = logLevel; 
    return *this; 
} 


template <typename T> 
Logger &operator<<(T const &value) { 
    LOG(mLogLevel) << value; 
    return *this; 
} 

更新2:

我想再次更新这个帖子给我的推理和证明我的最终解决方案。

我的推理是我的项目是一个抽象的演示。我试图证明日志库(和许多其他事物)可以从软件的核心功能中抽象出来。这也使得软件组件模块化。这样,我可以在不丢失语法的情况下更换easylogging ++库,因为它是在模块接口中实现的。

我最近的更新没有提到我如何克服插入链接的障碍,所以我想发布一个例子来说明我是如何做到的。以下代码是如何实现std :: cout类的语法的简化示例。

#include <iostream>   // For cout 
#include <string>   // For strings 
#include <sstream>   // For ostringstream 


enum logLevelT { 
    INFO_LEVEL, 
    WARNING_LEVEL, 
    ERROR_LEVEL, 
    FATAL_LEVEL 
}; 


class Logger { 
private: 
    std::string logName; 

public: 
    Logger(std::string nameOfLog, std::string pathToLogFile) { 
     logName = nameOfLog; 

     //TODO Configure your logging library and instantiate 
     //  an instance if applicable. 
    } 


    ~Logger(){} 


    // LogInputStream is instantiated as a temporary object. It is used 
    // to build the log entry stream. It writes the completed stream 
    // in the destructor as the object goes out of scope automatically. 
    struct LogInputStream { 
     LogInputStream(logLevelT logLevel, std::string nameOfLog) { 
      currentLogLevel = logLevel; 
      currentLogName = nameOfLog; 
     } 


     // Copy Constructor 
     LogInputStream(LogInputStream &lis) { 
      currentLogLevel = lis.currentLogLevel; 
      currentLogName = lis.currentLogName; 
      logEntryStream.str(lis.logEntryStream.str()); 
     } 


     // Destructor that writes the log entry stream to the log as the 
     // LogInputStream object goes out of scope. 
     ~LogInputStream() { 
      std::cout << "Logger: " << currentLogName 
         << " Level: " << currentLogLevel 
         << " logEntryStream = " << logEntryStream.str() 
         << std::endl; 

      //TODO Make a log call to your logging library. You have your log level 
      //  and a completed log entry stream. 
     } 


     // Overloaded insertion operator that adds the given parameter 
     // to the log entry stream. 
     template <typename T> 
     LogInputStream &operator<<(T const &value) { 
      logEntryStream << value; 
      return *this; 
     } 


     std::string currentLogName; 
     logLevelT currentLogLevel; 
     std::ostringstream logEntryStream; 
    }; 


    // Overloaded function call operator for providing the log level 
    Logger::LogInputStream operator()(logLevelT logLevel) { 
     LogInputStream logInputStream(logLevel, logName); 

     return logInputStream; 
    } 


    // Overloaded insertion operator that is used if the overloaded 
    // function call operator is not used. 
    template <typename T> 
    Logger::LogInputStream operator<<(T const &value) { 
     LogInputStream logInputStream(INFO_LEVEL, logName); 

     logInputStream << value; 

     return logInputStream; 
    } 
}; 



int main(int argc, char *argv[]) { 

    Logger logger1 = Logger("Logger1", "/path/to/log.log"); 
    Logger logger2 = Logger("Logger2", "/path/to/log.log"); 

    logger1(INFO_LEVEL) << "This is the " << 1 << "st test"; 

    logger2(ERROR_LEVEL) << "This is the " << 2 << "nd test"; 

    logger2 << "This is the " << 3 << "rd test"; 

    return 0; 
} 

我觉得我可以在命名和评论方面做得更好,但是我时间紧迫。我绝对接受任何评论或批评。

+0

它已经实现好和短。出于简单的原因你正在编写更多的代码! – ninja

你必须重载operator()因此,它将设置内部日志级别并回到*thisLogger&的类型,所以,超载operator<<与必要的日志级别集中返回的引用将正常工作。

事情是这样的:

Logger& Logger::operator()(LogLevel level) { 
    // set internal log level 
    return *this; 
} 
+0

非常感谢!这正是实现它所需要的。 – Blackwood