I have something equal to this:
auto dummy(std::function<int(int)> ifunc) {
auto vals = std::vector<int>(1000000);
for(auto& v: vals) {
v = ifunc(v);
}
}
Assuming the std::function does not bind to a lambda with state (althrough it might be bound to a lambda without state), what is the correct way of extracting the underlaying function pointer and exectuing it instead of the std::function?
This is my attempt, but it crashes regardles if I dereference the target or not.
auto dummy(std::function<int(int)> ifunc) {
auto vals = std::vector<int>(1000000);
auto&& target = *ifunc.target<int(int)>();
for(auto& v: vals) {
v = target(v);
}
}
The reason that
std::functionexists is to provide an abstraction of a function that has a particular signature. The actual function (or function object) held in thestd::functionobject does not have to have the signature that thestd::functionobject provides. For example, yourfunction<int(int)>object could hold a pointer to a function that takesdoubleand returnschar; the code inside thestd::functionobject takes care of the conversions.The
targettemplate member function returns a pointer to the target object only if the target object has the exact type specified by the template argument totarget. So, for example, if the target object takes adoubleand returnschar, the callingifunc.target<char(double)>will give you back a pointer to that function. Calling it with any other argument type will give you back a null pointer.In the code presented here, the call is
ifunc.target<int(int)>(), and that will return a null pointer unless the exact type of the target object is "function takingintand returningint".If you're going to use this template member function, you must check for a null pointer before doing anything else with the returned value.