Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to do a callback using a std::function() as reference?

I want to write a callback like this

template<typename T>
T GetValue(T (*CallBack) (const string), string in)
{
    T value;

    try
    {
        value = CallBack(in);
    }
    catch(std::invalid_argument &e)///if no conversion could be performed
    {
        cout << "Error: invalid argument: --> " + string(e.what());
        exit(-1);
    }
    return value;
}

int main()
{
    int integer=0;
    string data;
    cin>>data;
    integer=GetValue<int>(&std::stoi, data);
    return 0;
}

but it does not works. I have the following error.

error: cannot convert "|unresolved overloaded function type|" to "int
(^)(std::string)" {aka int (^)(std::__cxx11::basic_string)}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried other ways too. Like this:

class Object;
typedef int (Object::*CallBack)(const string&, std::size_t*, int);

Or like this:

    typedef int (std::*FCAST)(const string&);
    std::function<int(const string&)> f = (FCAST)&std::stoi;

error: address of overloaded function with no contextual type
information|

But i had not success. ¿Someone knows how to do it?

Thank you so much!!

>Solution :

Link: https://godbolt.org/z/69fTzW36z

You have to use the correct function signature – the one which stoi has.

As per this link: https://en.cppreference.com/w/cpp/string/basic_string/stol, the signrature is int stoi(const string&, size_t* pos = nullptr, int base = 10)

So making the changes (see // CHANGE HERE)

#include <iostream>
using namespace std;

// CHANGE HERE: see the function arguments to Callback
template<typename T>
T GetValue(T (*CallBack) (const string&, size_t* pos, int base), const string& in)
{
    T value;

    try
    {
        // CHANGE HERE: pass default arguments when calling the function
        value = CallBack(in, nullptr, 10);
    }
    catch(std::invalid_argument &e)///if no conversion could be performed
    {
        cout << "Error: invalid argument: --> " + string(e.what());
        exit(-1);
    }
    return value;
}

int main()
{
    int integer=0;
    string data = "1234";
    //cin>>data;
    integer=GetValue<int>(std::stoi, data);
    cout << integer << endl;
    return 0;
}

As mentioned in the comments, it’s better not to use standard library functions directly as function callbacks. Rather you may implement your own logic or you can use some other way like lambda functions, something like:

#include <iostream>
using namespace std;

template<typename T>
T GetValue(T (*CallBack) (const string&), const string& in)
{
    T value;

    try
    {
        value = CallBack(in);
    }
    catch(std::invalid_argument &e)///if no conversion could be performed
    {
        cout << "Error: invalid argument: --> " + string(e.what());
        exit(-1);
    }
    return value;
}

int main()
{
    string data = "1234";
    //cin>>data;
    int integer = GetValue<int>([](const string& s) { return stoi(s); }, data);
    cout << integer << endl;
    string data2 = "12345678900";
    long l = GetValue<long>([](const string& s) { return stol(s); }, data2);
    cout << l << endl;
    return 0;
}

Link: https://godbolt.org/z/31oKx5cjE

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading