首页 > 解决方案 > 在可变参数函数调用中执行一次语句

问题描述

Log为了输出有用的信息,我有以下课程:

class Log
{
public:
    enum {ALL = 0, DEBUG, ERROR};

    static void setDebugMode()
    {
        mDebugMode = true;
    }

    template <class T, class ... Args>
    static void write(unsigned int level, T&& arg, Args&& ... args)
    {
        switch (level)
        {
        //Important piece of information that needs to be displayed
        case ALL:
        {
            std::cout << std::forward<T>(arg);
            write(level, out, std::forward<Args>(args) ...);
            break;
        }
        //For reporting errors
        case ERROR:
        {
            std::cerr << std::forward<T>(arg);
            write(level, out, std::forward<Args>(args) ...);
            break;
        }
        //Additional information that is available in debug mode
        case DEBUG:
        {
            if(!mDebugMode)
                break; //If debug mode not set, get out

            std::cout << std::forward<T>(arg);
            write(level, out, std::forward<Args>(args) ...);
            break;
        }
        }
    }
    template <class T>
    static void write(unsigned int level, T&& t)
    {
        switch(level)
        {
        case ALL:
        {
            std::cout << std::forward<T>(t) << std::endl;
            break;
        }
        case DEBUG:
        {
            std::cout << std::forward<T>(t) << std::endl;
            break;
        }
        case ERROR:
        {
            std::cerr << std::forward<T>(t) << std::endl;
            break;
        }
        }
    }

private:
    Log();
    static bool mDebugMode;
};

我的问题如下:如何在不打印每个函数调用的情况下将“(DEBUG)”一次输出到控制台?也就是说,如果我使用传入的write函数作为级别,我想获得以下输出:DEBUG

(DEBUG) 13852 files loaded

标签: c++variadic-templatesvariadic-functions

解决方案


您可以通过使用折叠表达式而不是递归实现来简化代码并简化此前缀。(折叠表达式需要 C++17 编译器/编译器模式。)

// The only write function needed:
template <class ... Args>
static void write(unsigned int level, Args&& ... args)
{
    switch (level)
    {
    //Important piece of information that needs to be displayed
    case ALL:
    {
        (std::cout << ... << std::forward<Args>(args));
        break;
    }
    //For reporting errors
    case ERROR:
    {
        (std::cerr << ... << std::forward<Args>(args));
        break;
    }
    //Additional information that is available in debug mode
    case DEBUG:
    {
        if(!mDebugMode)
            break; //If debug mode not set, get out

        std::cout << "(DEBUG) ";
        (std::cout << ... << std::forward<Args>(args));
        break;
    }
    }
}

推荐阅读