将 Functor 作为参数传递给方法
我有以下两个展示命令模式的类。 (不幸的是,两者都有一个唯一的方法名称。)
//pseudocode
class Subscriber {
virtual void receive(const Event&) = 0;
}
class Dispatcher {
virtual void dispatch(const Event&) = 0;
}
我有一个类模板,其中包含某种类型的列表,以及迭代此列表的方法。
//pseudocode
template<typename T>
class Registry {
typedef list<T> ObjectList;
ObjectList _objects;
void iterate(const Event& event) {
for_each(_objects.begin(), _objects.end(), ...); //not sure what to do here
}
}
我想使用 mem_fun
创建一个函子,根据需要调用 receive
或 dispatch
。我能够创建一个简单的用例,只需调用一个没有任何参数的方法。即
//pseudocode
class Simple {
void simple() {/*...*/}
}
然后我迭代:
for_each(_objects.begin(), _objects.end(), mem_fun(&Simple::simple);
不幸的是,我不知道如何将 event
参数传递给 mem_fun。查看标题,我确实可以传递单个参数,但我不太熟悉 C++ 来理解我需要做什么。
最终,我想让迭代方法接受一种仿函数,这样它就会在列表中的每个方法上触发该方法。
我宁愿避免 Boost...我认为这完全有可能,无需将这个框架拖入其中。
谢谢!
I have the following two classes that exhibit the Command pattern. (Unfortunately, both have a unique method name.)
//pseudocode
class Subscriber {
virtual void receive(const Event&) = 0;
}
class Dispatcher {
virtual void dispatch(const Event&) = 0;
}
I have a class template that has a list of some type with a method to iterate over this list.
//pseudocode
template<typename T>
class Registry {
typedef list<T> ObjectList;
ObjectList _objects;
void iterate(const Event& event) {
for_each(_objects.begin(), _objects.end(), ...); //not sure what to do here
}
}
I would like to use mem_fun
to create a Functor that calls receive
or dispatch
as appropriate. I'm able to create a simple use case where I simply invoke a method without any params. I.e.
//pseudocode
class Simple {
void simple() {/*...*/}
}
and then I iterate:
for_each(_objects.begin(), _objects.end(), mem_fun(&Simple::simple);
Unfortunately, I have no idea how to get the event
param passed to mem_fun. Looking at the headers, it does appear that I can pass a single param, but I'm not well versed in C++ to understand what I need to do.
Ultimately, I would like to make the iterate
method accept a type of functor so it will fire that method on every method in the list.
I would prefer to avoid Boost...I think this is entirely possible without dragging this framework into the mix.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这可能是最直接的方法:
那么:
This may be the most straight-forward way:
Then:
如果我理解正确,您想要的是 std::bind2nd:
成员函数 Subscriber::receive 有两个参数。第一个是隐式
this
指针,第二个是const Event &
。std::bind2nd
,给定一个带有两个参数的函数f
,返回一个带有一个参数的函数f_1
,该函数调用原始函数f
第二个参数具有固定值。编辑:
要处理不同名称的调度函数,可以将调度函数作为模板参数:
不幸的是,似乎没有办法使
bind2nd 处理
const
引用参数,所以我的整个解决方案没有实际意义,除非复制Event
对象对你来说没问题。这将在 C++0x 中工作不过,std::bind 使调度函数成为模板参数的想法仍然有效。您甚至可以使用特征,使该机制更加灵活。
If I understand correctly, what you want is
std::bind2nd
:The member-function
Subscriber::receive
has two parameters. The first is the implicitthis
pointer, and the second theconst Event &
.std::bind2nd
, given a functionf
taking two arguments, returns a functionf_1
taking one argument, that invokes the original functionf
with a fixed value for the second argument.Edit:
To handle the different names of the dispatch functions, you can make the dispatch function a template parameter:
Unfortunately, there does not seem to be a way to make
bind2nd
handleconst
reference parameters, so my whole solution is moot, unless copyingEvent
objects is fine with you. This will work in C++0x withstd::bind
though, and the idea of making the dispatch function a template parameter is still valid. You can even use traits, to make that mechanism even more flexible.您可以创建一个函子类来包装您的 Subscriber 和 Dispatcher 类,例如,
您的对象列表可以将这些函子包装器存储为 MyFunctor 实例的列表。这样您就可以对它们调用 Execute() 并让它们委托给底层类。你真的应该有一个operator()而不是Execute()来获得一个“真正的”函子,但你明白了。
干杯
You could create a functor class that wraps your Subscriber and Dispatcher classes, e.g.
Your object list could then store these functor wrappers as a list of MyFunctor instances. This way you can call Execute() on them and let them delegate to the underlying classes. You should really have an operator() instead of Execute() to get a "real" functor, but you get the idea.
Cheers
检查您是否有 tr1。如果您有 tr1,它包含
std::bind
,它几乎完全等同于boost
实现。这应该可以在
标头中找到。如果您没有 tr1,请考虑使用 Boost。我强烈建议至少使用
boost::bind
,因为它是轻量级的并且仅是标头。如果您没有 tr1 并且不会使用 Boost,则需要混合使用
bind2nd
和mem_fun1
。第一个绑定第二个参数(在本例中是您的事件;该对象将是第一个),并且 mem_fun1 与 mem_fun 相同,但它需要两个参数,即要调用的对象和一个用于传递被调用的成员函数的参数。但这完全是一团糟。如果您确实可以访问
bind
,那么这相当容易。for_each(objects.begin(),objects.end(),bind(&Simple::simple,_1,事件))
Check if you have tr1. If you have tr1, it contains
std::bind
, which is almost exactly equivalent to theboost
implementation. This should be found in the<functional>
header.If you don't have tr1, consider using Boost. I would strongly suggest using at least
boost::bind
, as it's lightweight and header only.If you don't have tr1 and won't use Boost, you want to mix
bind2nd
andmem_fun1
. The first binds the second parameter (in this case, your event; the object will be the first) andmem_fun1
is the same asmem_fun
, but it expects two arguments, the object to be called on and one parameter to pass the member function being called. This is a complete mess, though.If you do have access to
bind
, it's fairly easy.for_each(objects.begin(), objects.end(), bind(&Simple::simple, _1, event))