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

然后它应该工作。

相关问题