【问题标题】:How to store template variadic arguments into std::ofstream?如何将模板可变参数存储到 std::ofstream 中?
【发布时间】:2018-07-27 15:28:12
【问题描述】:

我正在用 c++ 实现一个小的 Log 类

class Log
    {
    public:
        enum LogLevel
        {
            TRACE,
            DEBUG,
            INFO,
            WARNING,
            ERROR,
            FATAL
        };

        Log(): m_log(DEBUG) {} ;
        ~Log() {};

        int SetLogFilePath(const std::string& p_directory, const std::string& p_prefix);

        void SetLogLevel(const LogLevel p_logLvl);

        LogLevel& GetLogLevel();

        template<typename... Args>
        int Logging(const std::string& p_logLevel, const std::string& p_srcFile, const std::string& p_function, const int& p_line,
            const Args&& ... p_args);

    private:
        LogLevel m_log;
        std::string m_logFilePath;
    };

这是我的Log 类,我将目录和前缀存储到std::string m_logFilePath

template <typename ... Args>
    int Log::Logging(const std::string& p_logLevel, const std::string& p_srcFile, const std::string& p_function, const int& p_line,
        const Args&&... p_args)
    {
        std::ofstream log;
        log.open(m_logFilePath.c_str(), std::ios::out);
        if(!log.good())
        {
            std::cout << "Couldn't create file : " << m_logFilePath.c_str() << std::endl;
            return 0;
        }
        switch(p_logLevel)
        {
        case "TRACE":
            log << "(TRACE) ";
            break;

        case "DEBUG":
            log << "(DEBUG) ";
            break;

        case "INFO":
            log << "(INFO) ";
            break;

        case "WARNING":
            log << "(WARNING) ";
            break;

        case "ERROR":
            log << "(ERROR) ";
            break;

        case "FATAL":
            log << "(FATAL) ";
            break;

        default: break;
        }
        log << "Log Created at (Local Time): " << std::put_time(std::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())), "%c") << " ";
        log << "File Name: " << p_srcFile.c_str() << " " << "Function Name: " << p_function.c_str() << " " << "Line: " << p_line << " " << std::forward<Args>(p_args) << std::endl;
        log.close();
        return 1;
    }

以上是我对int Logging(...)函数的实现。

基本上,我存储日志级别、当前时间、源文件路径、函数名、代码行和一些可变参数。

我一直在寻找将多个可变参数存储到我的std::ostream log 中的方法,但找不到任何答案。

请帮忙!

【问题讨论】:

    标签: c++ c++11 templates logging variadic-templates


    【解决方案1】:

    如果我理解正确,您的问题是您不知道如何管理(在本例中:发送到输出流)参数的可变参数列表(基于可变参数模板)。

    我提出了一个在(未使用的)数组初始化上下文中使用逗号运算符功能的使用示例

    using unused = int[];
    
    int  cnt { -1 };
    
    (void)unused { 0, (oss << ", extra val "
                           << ++cnt << " [" << args << ']', 0)... };
    

    以下是一个简化但完整的示例

    #include <sstream>
    #include <iostream>
    
    template <typename ... Args>
    std::string  logging (std::string const & valA, std::string const & valB,
                          std::string const & valC, Args const & ... args)
     {
       std::ostringstream oss;
    
       using unused = int[];
    
       oss << "valA [" << valA << "], "
           << "valB [" << valB << "], "
           << "valC [" << valC << ']';
    
       int  cnt { -1 };
    
       (void)unused { 0, (oss << ", extra val "
                              << ++cnt << " [" << args << ']', 0)... };
    
       return oss.str();
     }
    
    int main()
     {
       auto l = logging("val1", "val2", "val3", 0, 1L, 2LL, 3U, 4UL, 5ULL,
                        6.0, 7.0f, "eight");
    
       std::cout << l << std::endl;
     }
    

    【讨论】:

    • 非常感谢您的回答!它运行良好
    猜你喜欢
    • 2013-05-27
    • 1970-01-01
    • 2019-03-29
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2017-05-29
    • 2014-01-19
    相关资源
    最近更新 更多