Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::bind can be assigned to argument-mismatched std::function?

I have code as follows:

#include <functional>
#include <iostream>
using namespace std;
void F(int x) {
  cout << x << endl;
}
int main() {
  std::function<void(int)> f1 = std::bind(F, std::placeholders::_1);
  f1(100);  // This works, will print 100.

  int x = 0;
  std::function<void()> f2 = std::bind(F, x);
  f2();  // This works, will print 0.

  std::function<void(int)> f3 = std::bind(F, x);
  f3(200);  // BUT WHY THIS WORKS?????? It prints 0.
  return 0;
}

My compiler info is: Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix

like image 437
lambda Avatar asked Mar 20 '15 03:03

lambda


People also ask

What is the use of std :: bind?

std::bind. The function template bind generates a forwarding call wrapper for f . Calling this wrapper is equivalent to invoking f with some of its arguments bound to args .

Why is it important to bind a function to its arguments C++?

Bind function with the help of placeholders helps to manipulate the position and number of values to be used by the function and modifies the function according to the desired output.

Does STD bind allocate?

The std::bind will be copied into heap allocated by the std::function and the std::function will be copied into heap allocated by the std::vector .

Why did we need to use an std :: function object?

It lets you store function pointers, lambdas, or classes with operator() . It will do conversion of compatible types (so std::function<double(double)> will take int(int) callable things) but that is secondary to its primary purpose.


1 Answers

That is correct behavior.

std::bind needs this looseness to fit its own specification.

Consider std::placeholders, which is used to mark parameters that are passed through to the bound function.

using std::placeholders;
std::function<void(int)> f2 = std::bind( F, _1 );
//  Parameter 1 is passed to                ^^
//  the bound function.

f2(7); // The int 7 is passed on to F

Similarly, there is _2 for the second parameter, _3 for the third, and so on.

That brings up an interesting question. How should this function object behave?

auto f3 = std::bind( F, _3 );

As you might imagine, it follows its own promise to pass the third parameter to F. Which means it does nothing to the first two parameters.

f3(10, 20, 30); // The int 30 is passed on to F. The rest?  Ignored.

So this is expected behavior, and possibly the only "feature" that std::bind holds over lambdas, even in C++14 and C++17.

The object produced by std::bind is designed to accept and ignore any extraneous parameters.

like image 115
Drew Dormann Avatar answered Sep 24 '22 04:09

Drew Dormann