Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::bind and std::function questions

Tags:

c++

c++11

int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
  1. Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
  2. Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
  3. Can lambdas replace all uses of std::bind?
  4. Is std::bind as optimal as implementing it as a lambda instead?
  5. What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
like image 607
David Avatar asked Nov 10 '11 16:11

David


1 Answers

Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?

I wouldn't describe the operator() of std::function as 'generated' (it's a regular member), but otherwise that is a good description. Optimizations are up to your compiler, but be warned that to optimize the indirection of std::function (which requires the use of type erasure) a compiler may need to perform heroics.

Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)

The call to std::bind returns a functor of unspecified type, and a copy of that functor is stored inside the x object. This copy will live as long as x itself. There is no name involved so I'm not sure what you mean by that.

Can lambdas replace all uses of std::bind?

No. Consider auto bound = std::bind(functor, _1); where functor is a type with an overloaded operator(), let's say on long and int. Then bound(0L) doesn't have the same effect as bound(0) and you can't replicate that with a lambda.

Is std::bind as optimal as implementing it as a lambda instead?

This is up to the compiler. Measure yourself.

What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?

It's a function type. Perhaps you're already familiar with the syntax for pointers/references to functions: void(*)(), int(&)(double). Then just remove the pointer/reference out of the type, and you just have a function type: void(), int(double). You can use those like so:

typedef int* function_type(long);
function_type* p; // pointer to function
like image 167
Luc Danton Avatar answered Oct 28 '22 17:10

Luc Danton