explain this one:
struct X
{
void foo(int arg) { cout << "X" << arg << endl; }
};
struct Y
{
void bar(int arg) { cout << "Y" << arg << endl; }
};
int main(int argc, char *argv[])
{
X x;
Y y;
mem_fun1_t<void, X, int> f1 = std::mem_fun(&X::foo);
boost::function<void (int)> f11 = std::bind1st(f1, &x);
f11(2);
mem_fun1_t<void, Y, int> f2 = std::mem_fun(&Y::bar);
boost::function<void (int)> f22 = std::bind1st(f2, &y);
f22(2);
f11 = f22; // WOW, THIS IS ALLOWABLE
}
How does Boost work, under the covers, to allow the line f11 = f22?
Seems unusual because f11 is a functor whose operator(int) calls an X::foo(int) with a this of x, so it would seem to be type specific to X, and then when I do same with f2/f22 its specific to Y, so how can the line f11 = f22 be allowed?
I actually want to do the f11 = f22 line, but I was surprised to see this was allowed, and am trying to understand how this isnt a type mismatch.
I know, "use the source, Luke", but the Boost sources are difficult to follow/comprehend with everything going on in there.
If you could, for your answer, show the classes that are expanded by the templatization, that would help.
I was thinking it was getting away with this by void* casting or something like that, but that seems like a hack, and beneath Boost to stoop down to that level. So whassup?
BTW, if you haven't encountered this kind of thing before, you should at least be surprised at this bit of magic, since you can't say "x = y" above, as that would clearly be disallowed since they are different types and there is no X::operator=(Y&), so that's where this amazement comes from - its a clever piece of subterfuge.