我有以下类结构,其中一个类继承自模板:
#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 );
}
目的是使 Worker 的 myErrorHandler ()接受生成回调的对象以及任意整数值。说实话,这是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的这个定义中尝试了一些简单的提示,但没有任何事情可以解决这个问题。
最后,我希望第3类能够拥有1对多看起来像Derived类实例的对象,每个对象都在Worker中进行回调。我希望模板是Derived的基类,因此对象可以ctor / dtor并构造其回调。
我在callback_t的定义中遗漏了什么?
***编辑更新:
上面的代码现在将编译;非常感谢你的建议。
我添加了boost :: asio标记,即使上面的代码已经完全删除了asio。模板/类将模拟一个asio timer-wrapper,它可以隐藏和管理自己的属性。我的协议完成处理程序(可以有多个状态计时器)将更容易阅读,并且定时器代码相同,但迄今为止复制/粘贴的位置将重构为公共类并继承。
答案 0 :(得分:0)
此处您不需要typename
,T
已知是一种类型。此外,您不能将参数名称用作function
参数的一部分。所以它应该只是boost::function<void(T*, int)>
。
您可能需要typename
中的Derived(Base<Derived>::callback_t cb)
。
答案 1 :(得分:0)
首先 - 正如其他人已经提到的那样 - 第7行中的typename
是错误的。但是,在这些上下文中,参数的名称可以作为函数参数给出,因此error_code
可以保留在那里。不需要进一步typenames
。
其次,绑定非静态成员函数指针的boost::bind
的第二个参数必须是指向该函数应被调用的对象的指针。使用this
作为第二个参数在这里会有所帮助,尽管从逻辑意义上说这是不是完全清楚。