开发者

boost::function in template baseclass error

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 arbit开发者_如何学运维rary 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.


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).


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜