2009-01-23 80 views
6

我正在研究資源管理類,並希望讓用戶提供一個函數作爲資源管理器構造函數的一部分「ReleaseResource」方法。從那裏請求資源時,將提供functor作爲將要返回的shared_ptr的刪除器,以便在資源不再使用時調用適當的方法。作爲變量保留仿函數

我遇到的問題是,這需要我將函數存儲在我的類中,而且我不完全確定如何執行此操作。使用仿函數通常當你模板的功能,像這樣:

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

,如果你打算使用仿函數在該函數的範圍,這是偉大的,但因爲模板超出範圍與我的功能不知道如何指定適當類型的變量來存儲仿函數供以後使用。

任何人都可以在正確的方向指向我嗎?

回答

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

您傳遞給boost::function的類型是函數類型。例如,int(bool, char)是返回int並採用bool和char的函數的類型。也就是說,如果你想立即構建shared_ptr,你不需要在某處存儲函子(boost::function需要new運算符),儘管對於非常小的函數,它將使用特殊技巧來僅使用堆棧分配(小緩衝區優化)):

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

的boost ::功能是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; 
}; 
+0

非常好!這正是我所期待的。非常感謝你! – Toji 2009-01-23 21:09:34

0

不知道這是否有幫助,但請注意,boost :: shared_ptr具有允許用戶包含定製解除分配(以及自定義分配器,如果需要)的構造函數覆蓋。這可能足以滿足你的需要(如果我正確地閱讀你的用例,它的設計就是考慮到這一點)。

+0

我已經意識到了這一點,並在上面的例子中使用它。我需要知道的是如何存儲傳遞給它的參數。 – Toji 2009-01-23 21:08:59

3

有兩種方法,其中biol只能模板化該類。

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我給將工作)

+0

除了這不是'binary_function'的工作方式。 binary_function是一個type-trait-giving-attribute屬性,而不是一個接口。它沒有應用運算符,因此即使提供參數,「func()」語句也是無效的。 查看有關boost :: function或tr1 :: function的其他答案。 – Aaron 2009-01-23 21:36:50