C++11 supports the flexible parameter list by template technology, it can help us to define a powerful function.
The article introduces how to create a log output function which looks like the following scene.

Log( IDebug, "one: ", 1, ", two: ", 2, ", three: ", 3 );

The first parameter IDebug indicates log level, the others can be any data type that will be print by std::cout. The function also gives us the file name and line number where it was used.

Output:

[Debug][../main.cpp:13] one: 1, two: 2, three: 3
[Debug][../cat.cpp:10] name: Cat

log.hpp

#ifndef LOG_HPP
#define LOG_HPP

#include <iostream>
#include <string>

#define Log( Level, ... ) print( Level, __FILE__, __LINE__, __VA_ARGS__ )

//#define Log( Level, format, ... ) print( Level, __FUNCTION__, __LINE__, format, __VA_ARGS__ )

enum E_Log_Level
{
    IError,
    IWarning,
    IDebug,
    IInfo
};

template <class T>
void print(const T &t) {
    std::cout << t << std::endl;
}

template <class T, class... Args>
void print(T parameter, Args... rest) {
    std::cout <<  parameter;
    print(rest...);
}

template <class... Args>
void print(E_Log_Level level, const char *name, int line,  Args... args)
{
    std::string str;
    switch ( level )
    {
    case IError:
        str = "[Error]";
        break;
    case IWarning:
        str = "[Warning]";
        break;
    case IDebug:
        str = "[Debug]";
        break;
    case IInfo:
        str = "[Info]";
        break;
    }
    str = str + "[" + name + ":";
    str = str + std::to_string( line ) + "] ";

    print( str, args...);
}

#endif // LOG_HPP

Use it in main.cpp and class Cat.

// main.cpp
// ...

using namespace std;

int main()
{
    Log( IDebug, "one: ", 1, ", two: ", 2, ", three: ", 3 );
    Cat cat;
    cat.ShowName();
    return 0;
}

cat.cpp

void Cat::ShowName()
{
    Log( IDebug, "name: ", m_Name );
}

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page