I have an existing function that converts a comma-delimited string of numbers into a vector, e.g. "1,2,3" becomes [1,2,3]
The function looks very roughly like:
bool ConvertStringToNumberList(string input, vector<int32_t>& output)
{
<bunch of code>
int32_t value = strtol(str, 0, /*base*/ 10);
<bunch of code>
}
I would like to change this into a template function that will work for int32_t, uint32_t, double, and float.
The problem is that, for each data type, there is a different parsing function (e.g. strtol, strtoul, strtod, strtof) that may take different number of parameters (e.g. strtod() does not take a "base" parameter).
How can I templatize the above code without repeating the <bunch of code>
but only changing the parsing function?
Just create the class which will have specializations, each with a static function to parse one of the types you want to support and use it from your function template.
E.g.:
template <typename T>
struct Converter {};
template <>
struct Converter<int32_t> {
static int32_t Parse(const std::string& str) {
return strtol(str, 0, /*base*/ 10);
}
};
template <>
struct Converter<double> {
static double Parse(const std::string& str) {
return atof(str);
}
};
template <typename T>
bool ConvertStringToNumberList(string input, vector<T>& output) {
// <bunch of code>
T value = Converter<T>::Parse(str);
// <bunch of code>
}
Alternatively, you may have plain Parse
function, which has overloads for each type,
but there you may get unexpected type promotions.
Unless you really want to do the whole job yourself, you're probably best off using something other than strtol
to start with. One possibility that would fit pretty nicely here would be boost::lexical_cast
:
template <class T>
ConvertStringToNumberList(string input, vector<T> &output) {
<bunch of code>
T value = boost::lexical_cast<T>(str);
<bunch more code>
}
lexical_cast
is pretty much equivalent to stuffing the string into a stringstream, then reading out the specified type, but it provide overloads to optimize for many of the most common types, so in many (most?) typical cases, it's quite a bit faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With