c++ - 将 std::bind 函数指针转换为 void* 并返回

标签 c++ casting stdbind

假设我想绑定(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));

与此同时,myfuncMyObj<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/

相关文章:

c++ - VB.NET Single 不等于 C float

c++ - 如何将 std::bind 作为通用引用类型传递?

c++ - 在 C++11 中,是否可以将模板函数包装在 std::function 中?

c++ - 'this'指针是否可以在c++头声明中使用?

c++ - 使用引用指向节点的指针的函数删除链表中的节点?

c++ - 如何用 C++ 编写 'pass reference by value' 包装器?

c++ - Qt:使用样式表将文本居中和左对齐

c++ - 使用 boost::filesystem 将文件路径从 Windows 转换为 Linux,然后再转换回来

sql - 错误类型强制转换 Postgresql 函数

转换无效*