I have a largish code base that does log_msg("Here comes %s", "the text")
, where log_message
is a macro that adds function name and line numbers to the log message.
GCC/G++ warn about errors when the format string doesn't match the supplied arguments. Unfortunately sometimes the code calls log_msg(get_the_text())
. The return value of get_the_text()
is unknown at compile time, so if it contains some printf
formatting sequences, the code will fall flat on its face.
What I'm looking for is a way to route the single argument usages through a different code path that doesn't interpret the formatting codes. I tried something like this hoping that the non-variadic case is more specific than the variadic one:
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg);
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg, ...);
I was hoping that the compiler would pick the single argument function when there are no variable args, but it complains about ambiguous calls.
Any ideas how to fix this without changing thousands of calls from
log_msg(get_the_text())
to log_msg("%s", get_the_text())
?
Thanks to @SamVarshavchik this is what I came up with:
#include <iostream>
#include <cstdio>
#include <tuple>
template<typename ... Args>
void log(Args ... args) {
if (sizeof...(args) == 1) {
auto t = std::make_tuple(args...);
std::puts(std::get<0>(t));
} else {
std::printf(args...);
}
}
int
main() {
log("Test %d");
log("%s %d\n", "Test", 1);
log([]{ return "%s";}());
return 0;
}