2009-08-06 65 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(); 
    } 

我想數據的私有成員_a綁定到顯示的成員函數,但我得到的編譯錯誤說我的參數類型,當我打電話d.Register不匹配, 我究竟做錯了什麼?謝謝。傳遞一個可調用對象的成員函數

回答

4

你想要做的並不完全清楚,但我會假設「綁定」是boost :: bind(或tr1 :: bind)。

一對夫婦的問題,綁定(顯示:: SomeTask,對此,_1):

  • 應該&顯示:: SomeTask
  • _1佔位符是沒有意義的,因爲這將創建一個一元函數對象和:
    • 顯示:: 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

我看不到'bind'返回什麼,但我絕對確定這與Action類不兼容。你也使用'複製語義',所以如果行動有空洞的實現,你將永遠不會被期望。 嘗試更改註冊(Action * action),並允許'bind'返回Action類的某個子項。

而且審查可能遷移到模板 - 比你甚至可以在所有

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

在這種情況下,你可能能夠與重寫操作()作爲函數的類使用,但沒有參數排除Action類。

0

首先,你必須使用&Display::SomeTask並給予Register一個返回類型,然後它取決於你的需求

  • 的包裝應*this呼籲SomeTask:省略_1
  • 包裝應在通過的Display對象上調用SomeTask:Shift _1代替this

然後,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(); 
    } 

然後它應該工作。

相關問題