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
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.