Swapnil
Swapnil

Reputation: 1568

std::bind with nullptr pointer

If I pass the nullptr to the std::bind function, how I check the validity of the 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;
}

The above program throw the segmentation fault.

Upvotes: 0

Views: 587

Answers (2)

jignatius
jignatius

Reputation: 6484

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

You're binding the instance of A in the function object to a nullptr. Hence the segmentation fault. You should pass the address of a valid instance of A (for the second parameter) that is going to outlive the invocation of this function object you create.

There's no way to check the function object is valid retrospectively. That is, before creating it you have to check that the pointer is valid.

Something like this makes more sense:

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

or

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

Nowadays, lambdas have superseded std::bind to create function objects. The equivalent lambda for what you're doing is:

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

Now using a nullptr for a makes no sense.

Upvotes: 0

eerorika
eerorika

Reputation: 238351

There is no way to access the bound parameters of the function object returned by std::bind.

You can check whether the pointer is null before binding it:

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

If you actually need a function object whose bound arguments can be accessed from the outside, then you need to write a named function object type. For example:

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

auto fun = Fun{ .ptr = getA() };
if (fun.ptr)
    // is "valid"

Upvotes: 2

Related Questions