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



我试图使用指向类成员函数的函数指针,然后使用std::bind在单独的函数中对该类的对象调用该函数。在这个单独的函数中,我可以绑定对象和函数指针一次,然后在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中无效?

谢谢!

Jim

std::bind不返回std::function对象,而是返回一个实现定义的绑定器类型。在这里,然后:

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

f被推导为这种绑定类型,并且这种绑定类型不必是可赋值的,只有CopyConstructable和MoveConstructable。引用标准,[func.bind.bind]/5:

备注:返回类型[std::bind]应满足MoveConstructible的要求。如果FDTiD都满足CopyConstructible的要求,则返回类型应满足CopyConstructible的要求。

FDTiD分别是绑定函数类型和参数类型。注意,它没有说明MoveAssignableCopyAssignable,这意味着不需要粘合剂来满足它们。这意味着分配

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

标准不要求其工作。

MSVC对std::bind的实现似乎坚持了这一点,而libc++(我相信它是Xcode附带的,但我不为Mac OS X开发)则更为宽松。

如果您希望fstd::function,则必须将其明确声明为一个:

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

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

1以及在其他任何地方都没有提到这种要求的事实

相关内容

最新更新