Very frequently in my C++ code I use the following type of helper function:
static inline std::string stringf(const char *fmt, ...)
{
std::string ret;
// Deal with varargs
va_list args;
va_start(args, fmt);
// Resize our string based on the arguments
ret.resize(vsnprintf(0, 0, fmt, args));
// End the varargs and restart because vsnprintf mucked up our args
va_end(args);
va_start(args, fmt);
// Fill the string
if(!ret.empty())
{
vsnprintf(&ret.front(), ret.size() + 1, fmt, args);
}
// End of variadic section
va_end(args);
// Return the string
return ret;
}
It has a few upsides:
- No arbitrary limits on string lengths
- The string is generated in-place and doesn't get copied around (if RVO works as it should)
- No surprises from the outside
Now, I have a few of problems with it:
- Kind of ugly with the rescanning of the varargs
- The fact that std::string is internally a contiguous string with space for a null terminator directly after it, does not seem to actually be explicitly stated in the spec. It's implied via the fact that ->c_str() has to be O(1) and return a null-terminated string, and I believe &(data()[0]) is supposed to equal &(*begin())
- vsnprintf() is called twice, potentially doing expensive throw-away work the first time
Does anybody know a better way?
Aucun commentaire:
Enregistrer un commentaire