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
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 .
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.
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 .
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With