执行绑定的std :: function会抛出std :: bad_function_call

时间:2013-06-19 20:35:20

标签: c++ runtime-error function-calls std-function stdbind

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

  

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

该参数是指向我自己的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();
    }
};

2 个答案:

答案 0 :(得分: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::function现在需要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
}

答案 1 :(得分: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...
}