0

これを説明してください:

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&) がないので、この驚きはそこから来ています。これは巧妙なごまかしです。

4

1 に答える 1