Having implemented CLogClass to make decent logging I also defined macro, but it works only with one parameter...
class CLogClass
{
public:
static void DoLog(LPCTSTR sMessage, ...);
};
#define DebugLog(sMessage, x) ClogClass::DoLog(__FILE__, __LINE__, sMessage, x)
Well, it fails when called with more than 2 parameters :( ... Is it possible at all to avoid it? Can it be translated to templates somehow?
EDIT: Variadic macros were introduced in VS 2005 (But i'm currently in VS 2003...). Any advices?
You could have a MYLOG macro returning a custom functor object which takes a variable number of arguments.
#include <string>
#include <cstdarg>
struct CLogObject {
void operator()( const char* pFormat, ... ) const {
printf( "[%s:%d] ", filename.c_str(), linenumber );
va_list args;
va_start( args, pFormat );
vfprintf( stderr, pFormat, args );
va_end( args );
}
CLogObject( std::string filename, const int linenumber )
: filename( filename ), linenumber( linenumber )
{}
std::string filename;
int linenumber;
};
#define MYLOG CLogObject( __FILE__, __LINE__ )
int _tmain(int argc, _TCHAR* argv[])
{
MYLOG( "%s, %d", "string", 5 );
return 0;
}
Note that it's not so hard to step over to the type-safe variant touched by this answer: you don't need any variadic arguments due to the chaining effect of operator<<
.
struct CTSLogObject {
template< typename T >
std::ostream& operator<<( const T& t ) const {
return std::cout << "[" << filename << ":" << linenumber << "] ";
}
CTSLogObject( std::string filename, const int linenumber )
: filename( filename ), linenumber( linenumber )
{}
std::string filename;
int linenumber;
};
#define typesafelog CTSLogObject( __FILE__, __LINE__ )
int _tmain(int argc, _TCHAR* argv[])
{
typesafelog << "typesafe" << ", " << 5 << std::endl;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With