I need to read csv file using already written library that returns column value always as string, so as part of validation and further processing i need to convert that string value to appropriate type (which can be double, int, enum, bool, date etc.) and here is what I had written but this is giving error that there are multiple overloads for stod/stoi etc. Also is there any better approach to accomplish this task.
bool convertFunction(T a, R& b,std::function<R (T)> fx)
{
bool isConverted = true;
try
{
b = fx(a);
}
catch(const std::exception& e)
{
isConverted = false;
}
return isConverted;
}
int main() {
std::string x = "2.54";
double y = 0.0;
bool isValid = convertFunction(x,y,std::stod);
std::cout<<"value of y is "<<y<<std::endl;
return 0;
}
CodePudding user response:
A totally generic approach might look as follows:
template <typename T>
bool convert(std::string const& text, T& value)
{
std::istringstream s(text);
s >> value;
char c;
return s && (s >> c, s.eof());
}
Reading yet another character is expected to fail with end-of-file flag to be set, this assures that the entire string has been read – then failing if trailing whitespace is available, though, so you might yet want to make the function tolerant against.
CodePudding user response:
If you really want to go the template route...
The fix for your implementation is to wrap std::stod
inside a lambda that takes a definitive set of parameters. Then assign that lambda to a std::function that matches what the template expects. I also updated the code to pass items by const reference a bit more consistently.
#include <string>
#include <functional>
#include <iostream>
template <typename T, typename R>
static bool convertFunction(const T& a, R& b, std::function<R (const T&)>& fx)
{
bool isConverted = true;
try
{
b = fx(a);
}
catch(const std::exception& e)
{
isConverted = false;
}
return isConverted;
}
int main() {
std::string x = "2.54";
double y = 0.0;
std::function<double (const std::string&)> S2D = [](const std::string& s) -> double {
return std::stod(s);
};
convertFunction(x, y, S2D);
std::cout<<"value of y is "<<y<<std::endl;
return 0;
}