2012-01-10 12 views
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 
} 

、私は明白なアプローチではなく、関数ポインタである仮想関数を使用してこの作業の罰金を、持っていますが、私はちょうどそれがいくつかの後押しをしようとする前にこの方法で作業を取得しようとしています: :バインド策略は後で...

+0

:次に、あなたがバインドを使用することができます

typedef void (*FFunc)(int i); 

:に

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

:私はこのような何かを意味しますstd :: function'](http://en.cppreference.com/w/cpp/utility/functional/function)と['std :: bind'](http://en.cppreference.com/w/ cpp/utility/functional/bind)? –

答えて

1

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

申し訳ありませんが、答えとして、それを提出することを意味するものではありませんでした、コメントすることを望んでいました。 Sample code

EDIT:これはC++スタイルなので、これはもっと楽しいかもしれませんか? b.test(static_cast<Foo::FFunc>(&Bar::barf2));

+0

まあ、そうです。それは私が避けたいと思っていた「不愉快なキャスティング」のようなものです! – Roddy

+0

@Roddy 'static_cast'を使うことができます。これは完全に有効なC++のキャストです。私は、 'boost :: bind'がそのようなキャストを内部的にどこかで使うと確信しています... – lapk

+0

あなたはそれが正しいC++ですか?関数(またはメンバ関数)のポインタを別の型にキャストして呼び出すことは違法です。この場合、 'b'から' Foo * 'へのキャスト(' test'を呼び出すとき)はおそらくノープですので、うまくいくかもしれませんが、保証されていないと思います(複数の仮想継承関与する)。 – Grizzly

1

Updated sample.

同様に、C++ 11 & & BOSTの私の知識として& & STLは最高ではありません、私はこれだけに助言することができますへ

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

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

悪い鋳造、それは

1

隠されている、あなたはもう少し関数ポインタを一般ことはできますか? `[あなたがC++ 11コンパイラを持っている場合は、多分あなたが使用することができ、

b.test(bind(&Bar::barf2, &b)); 
+1

'bind'以来、あなたはできません(' boost :: bind'や 'std :: bind'を意味していると思います。そうでなければ詳しく説明してください)は、関数ポインタではなく関数オブジェクトを返します。 'typedef function FFunc;'はうまくいくはずです(ただし、もちろんオーバーヘッドがたくさんあります)。 ' – Grizzly

+0

あなたは間違いありません。私は、関数ポインタではなく、boost:関数を使用します。バインドはポインタでは動作しません。 –

関連する問題