Consider this code,
#include <iostream>
#include <functional>
void pacifist()
{
std::cout << "I don't get involved in arguments. I'm a pacifist.\n";
}
int main() {
auto x = std::bind(pacifist);
x(); //OK: Makes perfect sense. No argument, being a pacifist!
x(5); //OK: but WTF!
x(5, 10); //OK: but WTF!!
x(5, 10, 15); //OK: but WTF!!!
}
And it compiles fine; it even runs —yes all invocations of x
calls pacifist
! (online demo):
$ clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
I don't get involved in arguments. I'm a pacifist. I don't get involved in arguments. I'm a pacifist. I don't get involved in arguments. I'm a pacifist. I don't get involved in arguments. I'm a pacifist.
Why is std::bind
designed to work with arguments in this case? Do they even make sense? Are they not misleading for programmers? It works with g++ as well.
The std::bind
documentation at cppreference says,
If some of the arguments that are supplied in the call to g() are not matched by any placeholders stored in g, the unused arguments are evaluated and discarded.
But it doesn't explain why is it designed to be so? What is the advantage? I see only disadvantages.
It is difficult to test and debug, which becomes more difficult in cases like this:
void call(std::function<void(int)> fun)
{
fun(5);
}
call(std::bind(pacifist)); //OK: again WTF!
But you might think, this wont compile, but it does and runs as well. Now it seems even more misleading because std::function<void(int)>
says "I take one int
argument" and thus it passes an int; but the function stored eventually doesn't take any int
at all.