试图用 std::bind 重新分配 std::function 并收到错误 "attempting to reference a deleted function"

attempting to reassign std::function with std::bind and getting error "attempting to reference a deleted function"

我正在尝试使用指向 class 成员函数的函数指针,然后使用 std::bind 在单独的函数中对 class 的对象调用该函数。在这个单独的函数中,我可以绑定对象和函数指针一次,然后在 Xcode 中绑定第二次,但不能使用 MSVS2015...

这是一些重现我遇到的问题的基本代码。在 Xcode:

上一切都可以正常编译和运行
class AClass
{
public:
    bool isNumber1()
    {
        return num == 1 ? true : false;
    }

private:
    int num;
};

typedef bool (AClass::*isFunction)();

bool checkIsFunc (AClass& object, isFunction function)
{
    auto f = std::bind(function, object);

    f = std::bind(function, object); // Error occurs here

    return f();
}

int main (int argc, char* argv[])
{

    AClass obj;

    bool outcome = checkIsFunc(obj, &AClass::isNumber1);

    return 0;
}

但是,使用 MSVS2015 时,出现以下错误:

error C2280: 'std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall AClass::* )(void),bool,AClass,>,AClass &> &std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall AClass::* )(void),bool,AClass,>,AClass &>::operator =(const std::_Bind<true,bool,std::_Pmf_wrap<bool (__thiscall AClass::* )(void),bool,AClass,>,AClass &> &)': attempting to reference a deleted function

知道我在这里做错了什么或者为什么这在 Xcode 中有效但在 VS 中无效吗?

谢谢!

吉姆

std::bind 不是 return 一个 std::function 对象,而是一个实现定义的活页夹类型。那么这里:

auto f = std::bind(function, object);

f推导出是这个binder类型,这个binder类型不一定是可赋值的,只需要CopyConstructible和MoveConstructible即可。根据标准,[func.bind.bind]/5:

Remarks: The return type [of std::bind] shall satifsy the requirements of MoveConstructible. If all of FD and TiD satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible.

FDTiD 分别是绑定函数类型和参数类型。请注意,它没有提及 MoveAssignableCopyAssignable,这意味着 1 不需要活页夹来满足它们。这意味着赋值

f = std::bind(function, object); // Error occurs here

标准不需要工作。

看来 MSVC 的 std::bind 实现坚持这一点,而 libc++(我相信它带有 Xcode,但我不为 Mac OS X) 比较宽松。

如果您希望 f 成为 std::function,您必须明确声明它:

std::function<bool()> f = std::bind(function, object);

然后重新分配也会起作用,因为 std::function 是可分配的。

1 以及其他任何地方都没有提到这样的要求