std::for_each 中的多态函子

发布于 2024-07-07 08:44:35 字数 821 浏览 4 评论 0原文

我正在尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

日记撕了你也走了 2024-07-14 08:44:35

您可以使用 function 中的函数适配器(及其垫片)。

#include <functional>

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

如果您的容器包含对象指针,请使用 mem_fun_ptr,否则使用 mem_fun。 除了这些之外,还有采用 1 个参数的成员函数的包装器:mem_fun1_ptr 和 mem_fun1。

@Evan:确实,您可以为每个对象调用具有相同参数的成员函数。 mem_fun1 包装器的第一个参数是 this 指针,第二个是成员函数参数:

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

参数越多,自己创建循环或创建循环就变得更具可读性具有表示参数的 const 成员变量的自定义仿函数。

You could use the function adapters (and their shims) from 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. Next to these, there are wrappers for member functions that take 1 argument: mem_fun1_ptr and mem_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 the this pointer, the second is the member function argument:

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.

漫漫岁月 2024-07-14 08:44:35

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) 
    ); 
}

但是,请注意,不支持 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.

// 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.

弄潮 2024-07-14 08:44:35

听起来你可以从 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.

故事还在继续 2024-07-14 08:44:35

忘记函子指针的所有包装,而是使用怎么样?
绑定(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.

时光倒影 2024-07-14 08:44:35

基于@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) );

与@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

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. binder2nd allows you to pass teh same number to various "this" pointers. binder1st allows you to pass various numbers to one "this" pointer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文