模板基类错误中的 boost::function
我有以下类结构,其中包含一个从模板继承的中间类:
#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 的定义中尝试了一些简单的提示,但没有解决这个问题。
最后,我希望第三个类能够拥有 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里不需要
typename
,T
已知是一种类型。此外,您不能使用参数名称作为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 offunction
argument. So it should be justboost::function<void(T*, int)>
.And you probably do need
typename
inDerived(Base<Derived>::callback_t cb)
.首先——正如 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, soerror_code
can stay there. No furthertypenames
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. Usingthis
as the second parameter will help here, though it is not totally clear whether this is intended, in a logical sense.