【问题标题】:Cast std::bind function pointer to void* and back将 std::bind 函数指针转换为 void* 并返回
【发布时间】:2016-12-04 23:55:45
【问题描述】:

假设我想绑定一个函数,然后将它作为 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&lt;dim&gt; 的方法,其类型为:

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.

我认为我的演员阵容有误,但我不知道声明类型的正确方法。这样做的正确方法是什么?

【问题讨论】:

    标签: c++ casting stdbind


    【解决方案1】:

    std::bind 的结果不是std::function,正如所示代码所假设的那样。

    因此,当所示代码将指向返回值的指针从 std::bind 转换为 void *,然后将其转换回指向 std::function 的指针,然后调用或访问函数对象时,结果如下在未定义的行为中。

    [func.bind.isbind]指定std::bind如下:

    模板未指定 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

    【讨论】:

    • 感谢您的回复,但是这里的解决方案到底是什么?我的返回类型应该是什么? std::function 是模板化类型,使用我选择的模板无法编译:“错误 C2893:无法专门化函数模板‘未知类型 std::invoke(_Callable &&,_Types &&...)’”
    • 正如我所写,解决方案是将std::bind 的返回值显式分配给适当的std::function,而不是auto
    • 谢谢,但我想我现在的困惑是我不知道如何输入适当的 std::function,因为我写的那个显然不是正确的 :)
    • 认真思考执行绑定的最终结果是什么。您将获得一个可调用对象,该对象接受某些参数并返回特定类型。那是你的std::function
    • 好的,让我试着说清楚一点。我尝试遍历绑定的函数签名。我显然没有做对。我花了很多时间玩不同的变化。如果您发现我在使用 std::function&, const std::vector&)> 作为绑定返回类型时做错了什么,请告诉我。
    猜你喜欢
    • 2012-10-25
    • 2020-06-11
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多