2009-12-11 22 views
6

関数ポインタを必要とするメソッドを呼び出す必要がありますが、実際に渡す関数はファンクタです。ここで私は何をしようとしているの例です:私は最後の行を取得する方法を見つけることができませんでしたC++のメンバ関数への関数ポインタ

#include <iostream> 
#include "boost/function.hpp" 

typedef int (*myAdder)(int); 

int adderFunction(int y) { return(2 + y); } 

class adderClass { 
    public: 
    adderClass(int x) : _x(x) {} 
    int operator() (int y) { return(_x + y); } 

    private: 
    int _x; 
}; 

void printer(myAdder h, int y) { 
    std::cout << h(y) << std::endl; 
} 

int main() { 
    myAdder f = adderFunction; 

    adderClass *ac = new adderClass(2); 
    boost::function1<int, int> g = 
    std::bind1st(std::mem_fun(&adderClass::operator()), ac); 

    std::cout << f(1) << std::endl; 
    std::cout << g(2) << std::endl; 
    printer(f, 3); 
    printer(g, 4); // Is there a way to get this to work? 
} 

は、プリンタ(G、4)、コンパイルします。これを動作させる方法はありますか?私のコントロールの唯一のものは、メソッドmainとクラスadderClassです。そのような

答えて

0

template<typename AdderT> 
void printer(AdderT h, int y) { 
    std::cout << h(y) << std::endl; 
} 

また、あなたがboost::functionは必要ありません。

adderClass ac(2); 
    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    printer(ac, 4); 
+0

それはうまくいくが、(私は言及するのを忘れていた)メソッド "printer"はコードで変更できない。 – JamieC

+0

私のコントロールにあるのは、メソッドmainとクラスadderClassです。 – JamieC

0

ブースト機能は通常の機能ポインタのように動作しますが、別のタイプです。だから、単に関数ポインタにboost関数を割り当てることはできません。あなたのコードで

あなたは単に

typedef boost::function1< int, int > myAdder; 

typedef int (*myAdder)(int); 

を置き換えることができ、すべてがうまくいきます。

2

OK]をクリックして、ここで別の試みです:

class CallProxy 
{ 
public: 
    static adderClass* m_instance; 
    static int adder(int y) 
    { 
     return (*m_instance)(y); 
    } 
}; 

adderClass* CallProxy::m_instance = NULL; 


int main() { 
    myAdder f = adderFunction; 

    adderClass ac(2); 

    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    CallProxy::m_instance = &ac; 
    printer(CallProxy::adder, 4); 
} 

トラブルは、あなたがそれを関数ポインタを送信しなければならないので、関数ポインタと他には何を受信するものとしてprinterをコンパイルしていることです。関数ポインタを使用すると、インスタンスを保持する人はいません。だから、この解決策は、静的なデータメンバーを使用してそれを行います。

このコードはスレッドセーフではないことに気をつけてください。同時にmainを実行する2つのスレッドは、m_instanceに2つの異なるものを置くことがあります。

+1

それはまたリエントラントではありません: 'printer'が' main'を呼び出した場合、あなたは困っています。しかし、私はそれが最低限可搬性であれば、制約が与えられればできることが最善だと思います。ポータブル以外のソリューションでは、例えば、オンザフライでコードを生成することができます。 –

+0

@Steve Jessop: 'main()'を呼び出すものは、とにかく未定義の振る舞いを引き起こします(§3.6.1/ 2: "関数mainはプログラム内で使用されません(3.2)")。 –

+0

@Jerry Coffinこの愚かな例の限られた範囲を超えて見てください。 – shoosh

関連する問題