0

やや醜いテンプレートコーディングを書き直そうとしています。

参考までに、オリジナルはこちら: https://codereview.stackexchange.com/questions/69545/recode-cc-trampoline-function-macros-using-templates

class Final : Base
{
    void Foo(){...}
    void Bar(){...}

    static void init(){
        // register_method populates a table of "extern C" function pointers.
        register_method( "foo", & FooHandler );
        register_method( "bar", & BarHandler );
    }
    :
    // trampolines
    static void FooHandler( void* pInstance ) {
        Final* f = reinterpret_cast<Final*>(pInstance);
        f->Foo();
    }
    static void BarHandler( void* pInstance ) {
        Final* f = reinterpret_cast<Final*>(pInstance);
        f->Bar();
    }
}

私のコードは CPython (C ライブラリ) とインターフェイスします。Python ランタイムは "myInst.foo" を認識し、テーブルで "foo" を検索して呼び出します。

Final::FooHandler( pointer_to_myInst );

(静的メソッドを C 関数ポインターに型キャストできることに注意してください)

FooHandler は、Final の正しいインスタンスの Foo メソッドにトランポリンします。

実際には、ハンドルはそれほどきれいではなく、それぞれが同一のハンドラーを必要とするメソッドが多数あります (ただし、関数アドレスは異なります)。

ハンドラーメカニズムを次のような基本クラスに抽象化しようとしています:

class Final : Base<Final>
{
    void Foo(){...}
    void Bar(){...}

    static void init(){
        // register_method populates a table of "extern C" function pointers.
        register_method( "foo", & Foo, Handler< &Foo> );
        register_method( "bar", & Bar, Handler< &Bar> );
    }
    :
}

class Base<Final>
{
    typedef void (Final::*FuncSig)(void);
    typedef void (Final::*HandlerSig)(void*); // takes 1 pvoid param

    void register_method( std::string name, FuncSig meth, HandlerSig handler ) {
        ...        
    }

    // generic trampoline
    template< Sig sig>
    static void Handler( void* pInstance ) {
        Final* f = reinterpret_cast<Final*>(pInstance);
        f ->* sig();
    }
}

現在、コンパイラ エラー ( http://ideone.com/vOtbcD ) でスタックしているため、この手法が有効かどうかさえわかりません。

これを行う方法はありますか、それとも本当にマクロが必要な場合の 1 つにすぎませんか?

参考までに、オリジナルはこちら: https://codereview.stackexchange.com/questions/69545/recode-cc-trampoline-function-macros-using-templates

ご覧のとおり、オリジナルはかなり醜いマクロを使用しています。

4

2 に答える 2