C-style macros with arbitrary number of parameters?

Started by
13 comments, last by Replicon 18 years, 11 months ago
Quote:Original post by 255
Good point bjogio. However, that would not work in a threaded program; you'd have to make a mechanism to get thread-specific objects.
OTOH how fast does error reporting really have to be?

yes, you're right. My mind is bended in single threaded way. When I'm referring to speed I talk about outofscope-driven destruction of objects. The macro is for error but it can be used for every log function right? N called to logger in a function will result in N construction and destruction. Anyway it's a trivial speech, when something is about linear complexity nothing wrong.

[ILTUOMONDOFUTURO]
Advertisement
Hold on! I do agree that there are better ways of doing this but this is a neat little hack..

#define LOG_ERROR(params) {Logger::Log ##params ;}

And you use it like this:

LOG_ERROR( (Logger::LOG_ERROR , "hardy %s har", "har") )

You then migt consider doing the following:

Logger::LogError(char *format,...);

In order to simplify the macro to this:

#define LOG_ERROR(params) {Logger::LogError ##params ;}
LOG_ERROR( ("hardy %s har", "har") )

Edit:

This can also be expanded...

#define MACRO(x,y,z) {varargfunc1 ##x ; varargfunc2 ##y ; normalfunc( z );}
MACRO( ("blah %d",3) , ("mary %s","jane") , 57 )
Simple with MSVC++:

Make Logger a singleton and do something like this:


Move the functionality of Logger::log to Logger::operator().

Then:

In debug:
#define LOG Logger::getInstance()

In release:
#define LOG __noop

Usage:

LOG("hardy %s har", "har");

That expands to Logger::getInstance()("hardy %s","har");, which is equivalent to
Logger::getInstance().operator()("hardy %s","har");
Quote:Original post by snk_kid
This is the first time i've come across that thread and you know all of those casts are unnecessary and pretty wrong, do you understand whats going on with that code? do you know why Sharlin's solution doesn't work, i can tell you if you want, in any case the correct code is just:

#define mkstr(args) static_cast<std::ostringstream&>(const_cast<std::ostringstream&>(std::ostringstream()) << args).str()



GCC isn't satisfied with that:
error: invalid const_cast of an rvalue of type `   std::ostringstream' to type `std::ostringstream&'


It needs a static_cast<const std::ostringstream &> around the constructor like so:
#define mkstr(args) static_cast<std::ostringstream&>( const_cast<std::ostringstream&>(static_cast<const std::ostringstream &>(std::ostringstream())) << args ).str()

and it works.
It's still cleaner than the original with the redundand upcast. Thanks for bringing this up again. Looks like back then I just settled for the first thing that worked.[smile]

What I'd still like to know is why doesn't this work (it prints the address of the first string constant, as discussed in the other thread):
std::cout << (static_cast<std::ostringstream&>(std::ostringstream() << "A" << 4)).str() << std::endl;
Sweet, thanks for all the awesome advice!

This topic is closed to new replies.

Advertisement