arennuit
arennuit

Reputation: 927

std::bind and std::function overlap or complementary?

I was looking at this exemple here, combining std::bind and std::function so as to create a command: really neat! The code for the command class goes like this:

class Command
{
 private:
   std::function<void ()> _f;

 public:
   command() {}
   command(std::function<void ()> f) : _f(f) {}

   template <typename T> void setFunction (T t) {_f = t ;}
   void execute()
    {
        if(!_f.empty())
            _f();
    }
};

Assuming I have a class MyClass containing a member function:

class MyClass
{
public:
    void myMemberFn() {}
}

Then the calling code looks like:

MyClass myClass;

command(std::bind(&MyClass::myMemberFn, myClass));

Though I must admit I do not really understand why std::function is needed in addition to std::bind. It seems to me that bind already encapsulates the function call, so why is function needed in Command? Couldn't Commandstore a std::bind rather than a std::function?

I have been looking at documentation for both std::bind and std::function and did not get it...

Anyone has an idea of why std::functionis needed?

PS: I am assuming std::bind ~= boost::bind and std::function ~= boost::function

Upvotes: 2

Views: 346

Answers (2)

PermanentGuest
PermanentGuest

Reputation: 5331

From the bind documnentation,

A function object of unspecified type T, for which std::is_bind_expression<T>::value == true, 
and which can be stored in std::function.

So

std::function<void ()> _f;

is needed to store the return value of

command(std::bind(&MyClass::myMemberFn, myClass));

so that this can be actually invoked later.

Upvotes: 1

JohannesD
JohannesD

Reputation: 14421

You have to store the result of the std::bind expression somewhere. The return type of std::bind itself is unspecified by the standard, so you cannot create a named member variable of that type (you can use the C++11 auto to create such a local variable, though!)

Also, any function taking std::function can (due to std::function implicit conversions) accept all sorts of callable objects, not just std::bind results - you can pass it a regular function pointer, a lambda, a custom function object, whatever that can be invoked.

Upvotes: 6

Related Questions