Roman
Roman

Reputation: 131038

How std::bind can be used?

One simple example that explains how std::bind can be used is as follows:

Assume that we have a function of 3 arguments: f3(x, y, z). We want to have a function of 2 arguments that is defined as: f2(x,y) = f3(x,5,y). In C++ we can easily do it with std::bind:

auto f2 = std::bind(f3, _1, 5, _2);

This example is clear to me: std::bind takes a function as its first argument and then it takes n other arguments, where n is the number of arguments of the function that is taken as the first argument for std::bind.

However, I found another use of bind:

void foo( int &x )
{
  ++x;
}


int main()
{
  int i = 0;

  // Binds a copy of i
  std::bind( foo, i ) (); // <------ This is the line that I do not understand.
  std::cout << i << std::endl;

}

It is clear that foo has one argument and with std::bind it was set to i. But but why do we use another pair of brackets after (foo, i)? And why we do not use output of the std::bind? I mean, why don't we have auto f = std::bind(foo, i)?

Upvotes: 5

Views: 419

Answers (4)

masoud
masoud

Reputation: 56479

It binds foo to a temporary object and then call it immediately:

  auto f = std::bind(foo, i);
  f();

Single line version:

std::bind(foo, i)();

Upvotes: 3

greggo
greggo

Reputation: 3229

Since the line

std::bind( foo, i ) () ;

... does the same thing as ...

foo(i);

... this isn't really a 'use' of std::bind which you might encounter in actual code, but it does serve as a simple illustration of what std::bind does, as explained in other answers.

As you point out, it's the usual case to store the result of the bind and call it somewhere else, otherwise there's no point in complicating the code with a std::bind in the first place.

Upvotes: 0

utnapistim
utnapistim

Reputation: 27365

The line

std::bind( foo, i ) ();

is equivalent to:

auto bar = std::bind( foo, i );
bar();

It creates a bound functor, then immediately calls it (using the second pair of parenthesis).

Edit: In the name of accuracy (and pointed out by @Roman, @daramarak) the two are not actually equivalent to calling the function directly: the i is passed by value to std::bind. The code equivalent to calling foo directly with i, would be:

auto bar = std::bind( foo, std::ref(i) );
bar();

Upvotes: 8

Your two questions pretty much answer each other. The trailing () is just a normal function call. Therefore, the expression means: "Bind i to foo; this will yield a function taking no parameters; then call the resulting function." Since the code's author decided the function is no longer needed after being called, it's not stored anywhere.

Upvotes: 2

Related Questions