I am attempting to write a logging function which takes a variadic argument list and prints in a safe manor.
vprintf
seems like the obvious answer, but I cannot seem to find a safe way to handle when the format string expects more arguments than were provided.
Additionally, it would be very nice if I could rearrange the order the parameters are printed.
This second requirement led me to boost::format
, which seems to be exactly what I want, except that it does not accept a va_list
for input.
I have done some extensive searching and the closest I could get was this solution:
boost::format with variadic template arguments
Unfortunately I am restricted to a specific gcc version which does not seem to include the std::initializer_list
In my searching, I have stumbled upon boost::preprocessor
which seems like it should be able to accomplish what I want, but I am struggling with the implementation of it.
So, ideally, what I'm searching for is something that works as follows:
void loggerFunc(const char* msgFormat, ...){
boost::format f(msgFormat);
va_list args;
va_start(args, msg);
f & MagicalFunctionCall(args);
va_end(args);
}
Where this MagicalFunctionCall(args)
would convert my args, for example:
1, "Test", 3.4, "OtherString"
into something like:
1 & "Test" & 3.4 & "OtherString"
I'm not necessarily tied to boost::preprocessor
or anything boost
really, but it would be ideal to accomplish this without pulling in any additional 3rd party dependencies (we already use boost elsewhere in the project). I just suggested those libraries, because they seemed to be the most promising in accomplishing all of the above.
Thanks!
Instead of Boost Format you could use the fmt library which supports older compilers ({fmt} 4 supports gcc 4.4):
void loggerFunc(const char *format, fmt::ArgList args) {
std::string s = fmt::format(format, args);
// log s
}
FMT_VARIADIC(void, loggerFunc, const char *)
The loggerFunc
generated by FMT_VARIADIC
can be used with variable number of arguments:
loggerFunc("{} {} {} {}", 1, "Test", 3.4, "OtherString");
Disclaimer: I'm the author of the fmt library.