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.
精彩评论