これを説明してください:
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
}
ブーストは内部でどのように機能し、f11 = f22 の行を許可しますか?
f11 は、operator(int) が x の this で X::foo(int) を呼び出すファンクターであるため、X に固有の型のように見えます。では、どうして f11 = f22 という行が許されるのでしょうか?
実際に f11 = f22 行を実行したいのですが、これが許可されていることに驚き、これが型の不一致ではないことを理解しようとしています。
「ソースを使用してください、ルーク」とはわかっていますが、Boost ソースは、そこで行われているすべてのことを理解するのが難しいです。
あなたの答えとして、テンプレート化によって展開されたクラスを表示できれば、それは役に立ちます。
これは void* キャストなどで回避できると思っていたのですが、それはハックのようで、Boost の下でそのレベルまで身をかがめます。それでどうした?
ところで、以前にこの種のことに遭遇したことがない場合は、上記の「x = y」と言うことができないため、少なくともこの魔法のビットに驚かれるはずです。これらは異なる型であるため、明らかに許可されていないためです。 X::operator=(Y&) がないので、この驚きはそこから来ています。これは巧妙なごまかしです。