假设我想绑定(bind)一个函数,然后将它作为 void * 传递给另一个函数,然后将其强制转换回来。
我有一个全局函数,我尝试在其中转换该函数:
void function_wrapper(void * func){
std::function<void(const std::vector<double>&, const std::vector<double>&)> * function = reinterpret_cast<std::function<void(const std::vector<double>&, const std::vector<double>&)> *>(func);
std::function<void(const std::vector<double>&, const std::vector<double>&)> function_ = *function;
}
同时,func 创建为:
auto func = std::bind(&MyObj<dim>::myfunc, this, _1, _2);
在这里dim
是等于 2
的模板化整数和 function_wrapper
通过
function_wrapper((void *)(&func));
与此同时,myfunc
是 MyObj<dim>
的一种方法类型:
void myfunc(const std::vector<double>& x, std::vector<double>& F) const;
当我尝试如上所述调用 function_wrapper 时,在取消引用时出现以下错误:
Exception thrown: read access violation.
std::_Func_class<void,std::vector<double,std::allocator<double> > const & __ptr64,std::vector<double,std::allocator<double> > const & __ptr64>::_Getimpl(...) returned 0xFFFFFFFFFFFFFFFF.
If there is a handler for this exception, the program may be safely continued.
我想我的类型转换打错了,但我不知道声明类型的正确方法。执行此操作的正确方法是什么?
最佳答案
std::bind
的结果不是 std::function
,如所示代码所假设的那样。
因此,当显示的代码将指向返回值的指针从 std::bind
转换为 void *
,然后将其转换回指向std::function
,然后调用或访问函数对象,这会导致未定义的行为。
[func.bind.isbind] 指定 std::bind
如下:
template<class F, class... BoundArgs> unspecified bind(F&& f, BoundArgs&&... bound_args);
返回值:“具有弱结果类型 (20.9.2) 的转发调用包装器 g。g(u1, u2, ..., uM) 的效果应为INVOKE (fd, std::forward(v1), std::forward(v2), ..., std::forward(vN), result_of_t)”。
就是这样。 std::bind
返回的类是未指定的,虽然给定的 C++ 实现肯定允许以某种方式生成 std::function
,但它不是需要这样做。
但是,解决方案很简单:将 std::bind
的返回值显式分配给适当的 std::function
。
关于c++ - 将 std::bind 函数指针转换为 void* 并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40965191/