variadic template is introduced in c++11. And I found the printf function can be replaced using it. However, cout is used in the implementation. I am wondering if it is poss
The safe_printf function by Andrei Alexandrescu is quite clever, but unfortunately has serious limitations:
Each argument is processed twice, once to check its validity and the second time to format it with printf. The check can be disabled in release mode to avoid overhead, but this seriously undermines safety.
It doesn't work with positional arguments.
There is a number of ways how you can improve on it:
Don't always forward formatting to printf once the argument type is established. For example, this benchmark shows that it's possible to implement integer formatting which is up to 6.7 times faster than sprintf.
To implement positional arguments you need to store arguments in an array because they need to be addressed by an index.
Here's an example of how it can be done:
class Arg {
private:
enum Type { INT, DOUBLE };
Type type;
union {
int int_value;
double dbl_value;
} u;
public:
Arg(int value) : type(INT) { u.int_value = value; }
Arg(double value) : type(DOUBLE) { u.dbl_value = value; }
// other types
};
void do_safe_printf(const char *format, const Arg *args, size_t num_args) {
// here we can access arguments by index
}
template
void safe_printf(const char *format, const Args&... args) {
Arg arg_array[] = {args...};
do_safe_printf(format, arg_array, sizeof...(Args));
}
Apart from supporting positional arguments, this approach will also minimize the code bloat as all the work is done by a single function do_safe_printf while safe_printf function template only places the arguments in an array.
These and other improvements have been implemented in the fmt library. According to benchmarks it is comparable or better both in speed and compiled code size to native printf implementation
Disclaimer: I'm the author of this library.