简体   繁体   English

std :: for_each中的多态仿函数

[英]Polymorphic functors in std::for_each

I'm trying to use stl algorithm for_each without proliferating templates throughout my code. 我正在尝试使用stl算法for_each而不会在我的代码中扩散模板。 std::for_each wants to instantiate MyFunctor class by value, but it can't since its abstract. std :: for_each想要按值实例化MyFunctor类,但它不能自抽象。 I've created a functor adapter class which passes a pointer around and then derefernces it when appropriate. 我已经创建了一个functor适配器类,它传递一个指针,然后在适当时将其转发。

My Question: 我的问题:

Does the STL or Boost already have such an adapter class? STL或Boost是否已经有这样的适配器类? 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 戴夫

You could use the function adapters (and their shims) from functional . 你可以从使用功能适配器(和它们的垫片) functional

#include <functional>

using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );

If your container contains pointers-to-objects, use mem_fun_ptr , else use mem_fun . 如果容器包含指向对象的指针,请使用mem_fun_ptr ,否则使用mem_fun Next to these, there are wrappers for member functions that take 1 argument: mem_fun1_ptr and mem_fun1 . 在这些之后,有成员函数的包装器,它们带有1个参数: mem_fun1_ptrmem_fun1

@Evan: indeed, you could call the member function with the same argument for each object. @Evan:的确,您可以使用每个对象的相同参数调用成员函数。 The first argument of the mem_fun1 wrappers is the this pointer, the second is the member function argument: mem_fun1包装器的第一个参数是this指针,第二个是成员函数参数:

for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );

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. 使用更多参数,自己创建循环变得更具可读性,或者创建具有表示参数的const成员变量的自定义函子。

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. tr1 :: ref可以在这里帮助你 - 这意味着它是一个参考包装器,这样你就可以通过参考标准算法引用普通对象来引用绑定或函数对象(甚至是抽象对象)。

// requires TR1 support from your compiler / standard library implementation
#include <functional>

void applyToAll(MyFunctor &f) {
    std::for_each(
        myvector.begin(), 
        myvector.end(), 
        std::tr1::ref(f) 
    ); 
}

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. 但是,请注意,没有decltype支持的编译器可能会拒绝传递对抽象类型的引用...因此,在获得C ++ 0x支持之前,此代码可能无法编译。

如果忘记了bind(functor_pointer,mem_fun1(&MyFunctor::operator());函数指针的所有包装,而是使用bind(functor_pointer,mem_fun1(&MyFunctor::operator());作为bind(functor_pointer,mem_fun1(&MyFunctor::operator());函数?这样,您不必担心以任何方式管理副本或形式。

Sounds like you could benefit from Boost::Function . 听起来你可以从Boost :: Function中受益。

If I remember correctly it's a header only library too, so it's easy to get it going with it. 如果我没记错的话,它也是一个只有标题的库,所以它很容易就可以了。

Building on @xtofl's answer, since the array contains int's and not "this" pointers, I think the correct incantation is 基于@ xtofl的答案,因为数组包含int而不是“this”指针,我认为正确的咒语是

class MyClass
{
  virtual void process(int number) = 0;
};
MyClass *instance = ...;

for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );

The only difference versus @xtofl's code is binder1st rather than binder2nd. 与@ xtofl代码的唯一区别是binder1st而不是binder2nd。 binder2nd allows you to pass teh same number to various "this" pointers. binder2nd允许您将相同的数字传递给各种“this”指针。 binder1st allows you to pass various numbers to one "this" pointer. binder1st允许您将各种数字传递给一个“this”指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM