-1

我想将成员函数绑定到std::function<void(void)>. 我听说成员函数需要一个额外的参数,即实例指针。因此我调用std::bind(&Class::Function, this, parameter)但是当我执行函数对象时,它会引发运行时错误。

Application.exe 中 0x748D4B32 处未处理的异常:Microsoft C++ 异常:内存位置 0x0114F4E8 处的 std::bad_function_call。

该参数是指向我自己struct的一个的指针。我怎么做错了?您还需要哪些额外信息?

更新:这是我的代码。

class ModuleRenderer
{
    struct Pass{ std::function<void()> Function; /* many more members... */ };
    std::vector<std::pair<std::string, Pass>> passes;

    enum Drawfunc{ FORMS, SKY, LIGHTS, QUAD, SCREEN };
    void AddPass(std::string Name, Drawfunc Function)
    {
        Pass pass;
        // set some of the members
        // ...

        passes.push_back(std::make_pair(Name, pass));
        Pass *pointer = &(passes.back().second);

        switch (Function)
        {
        case FORMS:
            pointer->Function = std::bind(&ModuleRenderer::DrawForms, this, pointer);
            break;

            // analogeously for the other cases
            // ...
        }
    }

    void DrawForms(Pass *pass)
    {
        // ...
    }

    // is called consecutively after adding all passes
    void Update()
    {
        for(auto i : passes)
            // some initializing based on members of pass
            i.Function();
    }
};
4

2 回答 2

1

上面的评论指出了几个不同的问题。要解决这些问题,请尝试对您的代码进行以下更改:

struct Pass{ std::function<void(Pass *)> Function; /* ... */ };

// ...

case FORMS:
  pointer->Function = 
      std::bind(&ModuleRenderer::DrawForms, this, std::placeholders::_1);
  break;

暂时不要将 绑定Pass *到函数调用,因为正如@molbdnilo指出的那样,当您AddPass()多次调用并且向量被调整大小时,该指针将变得无效。

由于std::functionnow 需要 a Pass *,因此您需要在调用它时提供正确的指针。

void Update()
{
    for(auto& i : passes) { // <-- take a reference, don't copy
        // some initializing based on members of pass
        i.Function( &i );   // pass Pass * to the function
}
于 2013-06-19T22:17:27.530 回答
1
passes.push_back(std::make_pair(Name, pass));
Pass *pointer = &(passes.back().second);

pointer当您稍后push_back并且向量增长时,这将变得无效。

您可以完全避免使用指针并传递相应对象的索引而不是指针。

pointer->Function = std::bind(&ModuleRenderer::DrawForms, this, passes.size() - 1);

// ...

void DrawForms(size_t i)
{
    Pass& pass = passes[i].second;
    // Handle as before...
}
于 2013-06-19T22:24:34.587 回答