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 的私有成员 _a 绑定到 Display 的成员函数,但是当我调用 d.Register 时出现编译错误说我的参数类型不匹配,我做错了什么?谢谢。

4

3 回答 3

4

你想要做什么并不完全清楚,但我假设“绑定”是 boost::bind (或 tr1::bind)。

bind(Display::SomeTask, this, _1) 的几个问题:

  • 它应该是 &Display::SomeTask
  • _1 占位符没有意义,因为它创建了一个一元函数对象并且:
    • Display::SomeTask 不带参数
    • Action::operator() 不带参数

使用 Boost.Function 和 Boost.Bind,您可以编写以下代码来实现我猜您正在尝试做的事情:

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();
};
于 2009-08-06T15:46:56.450 回答
1

我看不到“绑定”返回什么,但我绝对确定这与 Action 类不兼容。此外,您正在使用“复制语义”,因此如果 Action 的实现为空,您将永远不会得到想要的。尝试更改 Register(Action* action),并允许“绑定”返回 Action 类的某个子级。

还要查看迁移到模板的可能性——甚至可以完全排除 Action 类

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

在这种情况下,您可以将具有覆盖 operator() 的类用作没有参数的函数。

于 2009-08-06T14:59:54.070 回答
0

首先,你要使用&Display::SomeTask并给出Register一个返回类型,然后就看你的需要了

  • 包装器应该调用SomeTask*this省略_1
  • 包装器应调用SomeTask传递的Display对象: 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();
  }

然后它应该工作。

于 2009-08-06T15:47:27.087 回答