简体   繁体   中英

How to write a generic convert function in c++?

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;
}

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM