C++20 is adding a type-safe alternative to printf, called std::format, though it doesn't provide warnings at compile time.
__attribute__ ((format (printf, 1, 2)))
static inline std::string format(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
size_t bytes = vsnprintf(0, 0, fmt, args);
va_end(args);
va_list again;
va_start(again, fmt);
std::string result(bytes, '\0');
vsnprintf(&result[0], bytes + 1, fmt, again);
va_end(again);
return result;
}