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