std::for_each 中的多态函子
我正在尝试使用 stl 算法 for_each ,而不在整个代码中增加模板。 std::for_each 想要按值实例化 MyFunctor 类,但由于它是抽象的所以不能。 我创建了一个函子适配器类,它传递一个指针,然后在适当的时候取消引用它。
我的问题:
STL或Boost是否已经有这样的适配器类? 我不想重新发明轮子!
struct MyFunctor {
virtual ~MyFunctor() {}
virtual void operator()(int a) = 0;
}
namespace {
template<typename FunctorType, typename OperandType> struct
FunctorAdapter
{
FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
void operator()(OperandType& subject)
{
(*mFunctor)(subject);
}
FunctorType* mFunctor;
}; }
void applyToAll(MyFunctor &f) {
FunctorHelper<MyFunctor, int> tmp(&f);
std::for_each(myvector.begin(), myvector.end(), tmp); }
干杯,
戴夫
I'm trying to use stl algorithm for_each without proliferating templates throughout my code. std::for_each wants to instantiate MyFunctor class by value, but it can't since its abstract. I've created a functor adapter class which passes a pointer around and then derefernces it when appropriate.
My Question:
Does the STL or Boost already have such an adapter class? I don't want to have to reinvent the wheel!
struct MyFunctor {
virtual ~MyFunctor() {}
virtual void operator()(int a) = 0;
}
namespace {
template<typename FunctorType, typename OperandType> struct
FunctorAdapter
{
FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
void operator()(OperandType& subject)
{
(*mFunctor)(subject);
}
FunctorType* mFunctor;
}; }
void applyToAll(MyFunctor &f) {
FunctorHelper<MyFunctor, int> tmp(&f);
std::for_each(myvector.begin(), myvector.end(), tmp); }
Cheers,
Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
function
中的函数适配器(及其垫片)。如果您的容器包含对象指针,请使用
mem_fun_ptr
,否则使用mem_fun
。 除了这些之外,还有采用 1 个参数的成员函数的包装器:mem_fun1_ptr 和 mem_fun1。@Evan:确实,您可以为每个对象调用具有相同参数的成员函数。
mem_fun1
包装器的第一个参数是this
指针,第二个是成员函数参数:参数越多,自己创建循环或创建循环就变得更具可读性具有表示参数的 const 成员变量的自定义仿函数。
You could use the function adapters (and their shims) from
functional
.If your container contains pointers-to-objects, use
mem_fun_ptr
, else usemem_fun
. Next to these, there are wrappers for member functions that take 1 argument:mem_fun1_ptr
andmem_fun1
.@Evan: indeed, you could call the member function with the same argument for each object. The first argument of the
mem_fun1
wrappers is thethis
pointer, the second is the member function argument:With more arguments, it becomes more readable to create a loop yourself, or create a custom functor that has const member variables representing the arguments.
tr1::ref 可能会在这里帮助您 --- 它是一个引用包装器,以便您可以通过引用绑定或函数对象(甚至是抽象对象)通过引用标准算法来传递普通对象。
但是,请注意,不支持 decltype 的编译器可能会拒绝传递对抽象类型的引用...因此,在获得 C++0x 支持之前,此代码可能无法编译。
tr1::ref may help you here --- it's meant to be a reference wrapper so that you can pass normal objects by reference to bind or function objects (even abstract ones) by reference to standard algorithms.
However, NOTE that compilers without decltype support MAY reject passing a reference to an abstract type... so this code may not compile until you get C++0x support.
为什么不使用BOOST_FOREACH?
http://www.boost.org/doc/libs/ 1_35_0/doc/html/foreach.html
why not use BOOST_FOREACH?
http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html
听起来你可以从 Boost::Function 中受益。
如果我没记错的话,它也是一个仅包含头文件的库,因此很容易使用它。
Sounds like you could benefit from Boost::Function.
If I remember correctly it's a header only library too, so it's easy to get it going with it.
忘记函子指针的所有包装,而是使用怎么样?
绑定(functor_pointer,mem_fun1(&MyFunctor::operator());
作为函子? 这样,您就不必担心以任何方式管理副本。
What about forgetting all the wrapping of the functor pointer, and instead use
bind(functor_pointer,mem_fun1(&MyFunctor::operator());
as the functor? that way, you don't have to worry about managing the copy in any way shape or form.
基于@xtofl的答案,由于数组包含int而不是“this”指针,我认为正确的咒语是
与@xtofl代码的唯一区别是binder1st而不是binder2nd。 binder2nd 允许您将相同的数字传递给各种“this”指针。 binder1st 允许您将各种数字传递给一个“this”指针。
Building on @xtofl's answer, since the array contains int's and not "this" pointers, I think the correct incantation is
The only difference versus @xtofl's code is binder1st rather than binder2nd. binder2nd allows you to pass teh same number to various "this" pointers. binder1st allows you to pass various numbers to one "this" pointer.