You could just overload doStuff() with varargs...
*grumble stdio grumble*
void doStuff(const char* formatString, ...) {
va_list args;
va_start(args, formatString);
size_t strLen = vsnprintf(nullptr, 0, formatString, args);
std::vector<char> buffer(strLen + 1);
vsnprintf(buffer.data(), buffer.size(), formatString, args);
va_end(args);
//do stuff - your char* is now buffer.data()
}
or for more general usage
std::string stringf(const char* formatString, ...) {
va_list args;
va_start(args, formatString);
size_t strLen = vsnprintf(nullptr, 0, formatString, args);
std::string buffer(strLen + 1, 0);
vsnprintf(&buffer[0], buffer.size(), formatString, args);
va_end(args);
buffer.pop_back();
return buffer;
}
doStuff(stringf("derp %d herp", 42).c_str());