模板基类错误中的 boost::function

发布于 2024-11-27 23:32:49 字数 1560 浏览 3 评论 0原文

我有以下类结构,其中包含一个从模板继承的中间类:

#include <boost/function.hpp>
#include <boost/bind.hpp>

template<class T>
struct Base {
  typedef
      boost::function<void (T*,int)>
  callback_t;

  callback_t  m_callback;

  Base(callback_t  cb):  
      m_callback(cb)
  {}
  virtual ~Base()
  {}

  void handleError(int error_code) {
      m_callback(this,error_code);
  }
};  

struct Derived: public Base<Derived> {
  Derived(Base<Derived>::callback_t cb):
      Base<Derived>(cb)
  {}
  ~Derived()
  {}
};

struct Worker {
  Derived  m_o;

  void myErrorHandler(Derived* o,int error_code)
  {}

  Worker(void): 
      m_o(boost::bind(&Worker::myErrorHandler,this,_1,_2))
  {}
};

int main(int argc,const char** argv)
{
   Worker  m;
   return( 0 );
}

目的是使 WorkermyErrorHandler() 接受生成回调的对象以及任意整数值。说实话,这是 asio 回调处理程序的简化版本,但为了简洁起见,我去掉了 asio。

编译器抱怨模板内的 *typedef...callback_t* ,说:

../src/templates.cpp:13: error: a call to a constructor cannot appear in a constant-expression
../src/templates.cpp:13: error: template argument 1 is invalid

我已经通过将 typename 放置在callback_t 的定义中尝试了一些简单的提示,但没有解决这个问题。

最后,我希望第三个类能够拥有 1 到多个看起来像派生类实例的对象,每个对象都在 Worker 中获得回调。我希望模板成为 Derived 的基类,以便对象可以 ctor/dtor 并构造其回调。

我在callback_t的定义中遗漏了一些东西吗?

***编辑更新:

上面的代码现在将编译;非常感谢您的建议。

我添加了 boost::asio 标签,尽管上面的代码已经完全删除了 asio。模板/类将模拟一个 asio 计时器包装器,它可以隐藏和管理它自己的属性。我的协议完成处理程序(可以有多个状态计时器)将更容易阅读,并且计时器代码相同但迄今为止复制/粘贴的地方将重构为公共类并被继承。

I have the following class structure with an intermediate class which inherits from a template:

#include <boost/function.hpp>
#include <boost/bind.hpp>

template<class T>
struct Base {
  typedef
      boost::function<void (T*,int)>
  callback_t;

  callback_t  m_callback;

  Base(callback_t  cb):  
      m_callback(cb)
  {}
  virtual ~Base()
  {}

  void handleError(int error_code) {
      m_callback(this,error_code);
  }
};  

struct Derived: public Base<Derived> {
  Derived(Base<Derived>::callback_t cb):
      Base<Derived>(cb)
  {}
  ~Derived()
  {}
};

struct Worker {
  Derived  m_o;

  void myErrorHandler(Derived* o,int error_code)
  {}

  Worker(void): 
      m_o(boost::bind(&Worker::myErrorHandler,this,_1,_2))
  {}
};

int main(int argc,const char** argv)
{
   Worker  m;
   return( 0 );
}

The intent is to make Worker's myErrorHandler() accept the object which generated the callback along with an arbitrary integer value. Truth to tell, this is a simplified version of an asio callback handler, but I took out the asio for the sake of brevity.

The compiler complains about the *typedef...callback_t* inside the template, saying:

../src/templates.cpp:13: error: a call to a constructor cannot appear in a constant-expression
../src/templates.cpp:13: error: template argument 1 is invalid

I've tried trivial hints by placing typename in this definition of callback_t, but nothing gets past this problem.

In the end I want a 3rd class to be able to have 1 to many objects that look like Derived class instances, each getting their callback in Worker. I want the template to be baseclass to Derived so the object can ctor/dtor and construct its callback.

Am I missing something in my definition of callback_t?

***EDIT UPDATE:

The above code will now compile; many thanks for the suggestions.

I added the boost::asio tag even though the above code has had the asio completely removed. The template/class will model an asio timer-wrapper that can hide and manage its own attributes. My protocol completion handler (which can have multiple state timers) will be a bit simpler to read, and places where timer code is identical, but hitherto copy/pasted, will refactor into common classes and be inherited.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉宸 2024-12-04 23:32:49

这里不需要 typenameT 已知是一种类型。此外,您不能使用参数名称作为 function 参数的一部分。所以它应该只是 boost::function

而且您可能确实需要 Derived(Base::callback_t cb) 中的 typename

You don't need typename here, T is known to be a type. Also, you can't use argument names as part of function argument. So it should be just boost::function<void(T*, int)>.

And you probably do need typename in Derived(Base<Derived>::callback_t cb).

惯饮孤独 2024-12-04 23:32:49

首先——正如 cat else 已经提到的——第 7 行中的 typename 是错误的。但是,在这些上下文中,参数的名称可以作为函数参数给出,因此 error_code 可以保留在那里。不需要更多的类型名称

其次,绑定非静态成员函数指针的 boost::bind 的第二个参数必须是指向要调用该函数的对象的指针。使用 this 作为第二个参数在这里会有所帮助,尽管从逻辑意义上来说,这是否是有意为之并不完全清楚。

First of all -- as cat else already mentioned -- the typename in line 7 is wrong. However, in those contexts the name of the parameter can be given as the function argument, so error_code can stay there. No further typenames are necessary.

Second, the second argument of a boost::bind that is binding a non-static member function pointer must be a pointer to the object the function shall be called on. Using this as the second parameter will help here, though it is not totally clear whether this is intended, in a logical sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文