保留函子作为变量

时间:2009-01-23 20:00:44

标签: c++ functor

我正在开发一个资源管理类,并希望让用户为“ReleaseResource”方法提供一个仿函数,作为资源管理器构造函数的一部分。从那里请求资源时,将提供functor作为我将返回的shared_ptr的删除器,以便在不再使用资源时调用适当的方法。

我遇到的问题是,这要求我在我的班级中存储仿函数,而我并不完全确定如何做到这一点。通常在使用仿函数时,您可以像这样模拟函数:

template<class MyFunctor> MyMethod(MyFunctor f) {
    f();
}

如果您打算在该函数的范围内使用该仿函数,这很好,但由于该模板超出了该函数的范围,我不确定如何指定适当类型的变量来存储该仿函数供以后使用。

有人能指出我在正确的方向吗?

3 个答案:

答案 0 :(得分:8)

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::function<void()> g = f;
    g();
}

传递给boost::function的类型是函数类型。例如,int(bool, char)是返回int并获取bool和char的函数的类型。也就是说,如果你想立即构建shared_ptr,你不需要将functor存储在某个地方(boost::function需要new运算符,即使对于非常小的仿函数,它也会使用只使用堆栈分配(小缓冲区优化)的特殊技巧):

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::shared_ptr<T> ptr(new T, f);
}

boost :: function是tr1的一部分,将成为下一个官方C ++标准的一部分。例如:

struct Manager {
    template<typename Deleter>
    Manager(Deleter d) 
        :deleter(d) {

    }

    boost::shared_ptr<Resource> allocate() {
        ...
        return boost::shared_ptr<Resource>(resource, deleter);
    }

private:
    boost::function<void(Resource *)> deleter;
};

答案 1 :(得分:3)

有两种方法,两种方法都可以用来模板化。

template <MyFunctor>
class MyClass
{
   MyFunctor   func;
  public:
    MyClass(MyFunctor f) :func(f)
    { }


    MyMethod() 
   {
       func();
   }
}

这需要您知道仿函数的类型。为避免这种情况,我们可以使用工厂:

 template<MyFunctor>
 MyClass<MyFunctor>  MakeFunctorClass(MyFunctor f)
 {     
     return MyClass<MyFunctor>(f);       
 }

或者,由于很可能大多数仿函数签名都是相同的,只有一小部分改变,我们可以使用:

template <MyType>
class MyClass
{
   typedef std::binary_function<MyType, MyType, bool>  MyFunctor;
   MyFunctor func;
  public:


    MyMethod(MyFunctor f) 
   {
       func = f;
       func();
   }
}

这使得使用更简单:

 bool AreEqual(int, int); 
 MyClass<int> myc;
 myc.MyMethod(AreEqual);

以昂贵的更复杂的定义(即,我不保证我给出的binary_function typedef会起作用)

答案 2 :(得分:0)

不确定这是否有帮助,但请注意boost :: shared_ptr具有构造函数覆盖,允许用户包含自定义解除分配(以及自定义分配器,如果需要)。这可能足以满足您的需求(如果我正确地阅读您的用例,那么它的设计考虑到了这一点。)