微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std :: bind与nullptr指针

如何解决std :: bind与nullptr指针

如果我将nullptr传递给std::bind函数,如何检查std::function的有效性?

// Example program
#include <iostream>
#include <string>
#include <functional>

class A
{
    std::string si;
    public: 
    A(std::string s) : si(s) {}  
    
    int getData(std::string x) { 
        si += x;
        return si.size(); }
};

A* getA()
{
    return nullptr;
}

int main()
{
    auto fun = std::bind(&A::getData,getA(),std::placeholders::_1);
    
    if (getA() == nullptr)
      std::cout << "nullptr";
    
    std::cout << "output : " << fun("str");
    
    return 0;
}

上面的程序抛出了分割错误

解决方法

无法访问std::bind返回的函数对象的绑定参数。

您可以在绑定指针之前检查指针是否为空:

if(A* ptr = getA())
{
    auto fun = std::bind(&A::getData,ptr,std::placeholders::_1);

如果实际上需要一个可以从外部访问其绑定参数的函数对象,则需要编写一个命名函数对象类型。例如:

struct Fun {
    A* ptr;
    int operator()(const std::string& x) {
        return ptr->getData(x);
    }
};

auto fun = Fun{ .ptr = getA() };
if (fun.ptr)
    // is "valid"
,
auto fun = std::bind(&A::getData,getA(),std::placeholders::_1);

您正在将函数对象中的A实例绑定到nullptr。因此,分割错误。您应该传递A(用于第二个参数)的有效实例的地址,该实例的寿命将超过您创建的此函数对象的调用。

无法追溯检查功能对象是否有效。也就是说,在创建它之前,您必须检查指针是否有效。

像这样的事情更有意义:

A a("hello");
auto fun = std::bind(&A::getData,&a,std::placeholders::_1);

A* ptr = getA();
if (ptr)
{
    auto fun = std::bind(&A::getData,std::placeholders::_1);
    ...
}

如今,lambda取代了std::bind来创建函数对象。等价于您正在执行的lambda:

auto fun = [a](std::string str) { return a->getData(str); }

现在为nullptr使用a毫无意义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。