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 );
}
[…] The file log.h can found in the article Create Log Output Function Based On Variable-parameter List . […]