2009-08-06 16 views
0
class Action { 
    public: 
     void operator()() const; 
    } 

    class Data { 
    public: 
     Data(); 
     ~Data(); 
     Register(Action action) { _a = action; } 

    private: 
     Action _a; 
    } 

    class Display { 
    public: 
     Display(Data d) { d.Register(bind(Display::SomeTask, this, _1)); } 
     ~Display(); 
     void SomeTask(); 
    } 

Dataのprivateメンバー_aをDisplayのメンバ関数にバインドしたいが、d.Registerを呼び出すと、引数の型が一致しないというコンパイルエラーが発生する、私は間違って何をしていますか?ありがとう。呼び出し可能なオブジェクトをメンバ関数に渡す

答えて

4

あなたがしようとしていることは完全にはっきりしていませんが、私は "bind"はboost :: bind(またはtr1 :: bind)であると仮定します。

バインドでの問題のカップル(表示:: SomeTask、この、_1):それはそれは単項関数を作成しますので、_1プレースホルダは、意味をなさない&表示:: SomeTask

  • でなければなりません

    • 対象と:
      • 表示:: SomeTaskが
      • アクション::演算子()は引数
      を取らない引数を取りませんBoost.FunctionとBoost.Bindを使用して

    は、ここにあなたが私はあなたが何をしようとしていると思うものをacheiveに書き込むことができるものです:

    typedef boost::function<void(void)> Action; 
    
    class Data { 
    public: 
        Data(); 
        ~Data(); 
        Register(Action action) { _a = action; } 
    
    private: 
        Action _a; 
    }; 
    
    class Display { 
    public: 
        Display(Data d) { d.Register(bind(&Display::SomeTask, this)); } 
        ~Display(); 
        void SomeTask(); 
    }; 
    
  • 1

    「バインド」が返すものは表示されませんが、これはアクションクラスと互換性がないことは絶対に確信しています。また、あなたは 'コピーセマンティック'を使用しているので、アクションに空のインプリメンテーションがある場合、あなたは決して望みません。 変更登録(Action *アクション)を試し、 'bind'がActionクラスの子を返すことを許可します。

    はまた、テンプレートに移行する可能性を検討 - あなたもあなたは、引数なしの関数としてオーバーライドされた演算子()を持つクラスとして使用することができる可能性があり、この場合には、すべての

    template <class A> 
    class Data { ... 
    Register(A action)... 
    A _a; 
    ... 
    

    でActionクラスを除外することができるよりも。

    0

    まず、あなたは&Display::SomeTaskを使用してRegister与えなければなりません戻り値の型、およびそれはあなたのニーズ

    • に依存ラッパーが*thisSomeTaskを呼び出す必要があります。_1を省略します。
    • ラッパーは、DisplayオブジェクトのSomeTaskを呼び出します(thisの代わりに_1)。

    次に、boost::bindは、指定された関数を呼び出す複雑な合成タイプを返します。あなたはそれを保存する方法が必要です。それはboost::functionが便利です。これはあなたがそれを行う方法です。

    class Display; // forward-declaration 
        class Data { 
        public: 
         Data(); 
         ~Data(); 
    
         template<typename Action> 
         void Register(Action action) { _a = action; } 
    
        private: 
         boost::function<void(Display&)> _a; 
         // if wrapper should call it on `*this` 
         // boost::function<void()> _a; 
        } 
    
        class Display { 
        public: 
         // this currently makes no sense. You pass a copy. Probably you 
         // should consider pass-by-reference or processing "d" further. 
         Display(Data d) { d.Register(bind(&Display::SomeTask, _1)); } 
         // wrapper should call it on `*this`: 
         // Display(Data d) { d.Register(bind(&Display::SomeTask, this)); } 
         ~Display(); 
         void SomeTask(); 
        } 
    

    次に動作するはずです。