2

派生クラスから関数ポインターを期待する基本クラス関数に関数を渡そうとしていますが、コンパイラエラーが発生します。

[BCC32 Error] E2034 Cannot convert 'void (Bar::*)(int)' to 'void (Foo::*)(int)'

これは設計どおりだと思いますが、不快なキャストを伴わない方法はありますか?boost::bindここで私を助けることができますか?

#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

class Foo
{
public:
  typedef void (Foo::*FFunc)(int i);

  void test(FFunc f)
  {
    CALL_MEMBER_FN(*this,f)(123);
  }

  void barf1(int i) {};
};

class Bar : public Foo
{
public:
  void barf2(int i) {};
};

void ffff()
{
  Foo f;
  f.test(Foo::barf1); // works

  Bar b;
  b.test(Bar::barf1); // works
  b.test(Bar::barf2); // ERROR
}

ちなみに、私は仮想関数を使用してこれを正常に機能させています。これは、関数ポインターではなく明らかなアプローチですが、後でブースト::バインドのトリックを試みる前に、このように機能させようとしています...

4

3 に答える 3

1

b.test( ( Foo::FFunc )&Bar::barf2 );

申し訳ありませんが、回答として送信するつもりはありませんでした。コメントしたかったのです。サンプルコード

編集:まあ、それはC ++スタイルなので、おそらくこれはより「楽しい」キャストですか?サンプルを更新しました。

b.test( static_cast< Foo::FFunc >(&Bar::barf2) );

于 2012-01-10T13:28:15.770 に答える
1

関数ポインタをもう少し一般化できますか?私はこのようなものを意味します:

typedef void (Foo::*FFunc)(int i);

に:

typedef void (*FFunc)(int i);

次に、bindを使用できます。

b.test(bind(&Bar::barf2, &b));
于 2012-01-10T14:02:06.963 に答える
1

同様に、c++11 && bost && stl に関する私の知識は最善ではないため、次のようにアドバイスすることしかできません。

 template <typename T>
    void test(void (T::*f)(int))
  {
    CALL_MEMBER_FN(static_cast<T&>(*this),f)(123);
  }

他のすべてのコードはあなたのものと同じです。

悪いキャスティングですが、それは隠されています

于 2012-01-10T13:37:18.397 に答える