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::function
exists is to provide an abstraction of a function that has a particular signature. The actual function (or function object) held in thestd::function
object does not have to have the signature that thestd::function
object provides. For example, yourfunction<int(int)>
object could hold a pointer to a function that takesdouble
and returnschar
; the code inside thestd::function
object takes care of the conversions.The
target
template 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 adouble
and 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 takingint
and 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.