2011-10-18 94 views
1

我想在C++中編寫通用包裝器。這是我到目前爲止已經寫的:通用包裝C++

//primary template 
template<typename T> 
class function 
{ 
}; 
//partially specialized template 

template<typename T, typename U, typename V> 
class wrapper<T(U,V)> 
{ 
private: 
    //typedef pointer to function 
    typedef T (*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(U a, V b) 
    { 
    return f(a,b); 
    } 
}; 

可使用實例化,例如:

wrapper<double(double, double)> someWrapper(&someFunction); 

我在想,如果有人能在以下方面指出我在正確的方向如何修改包裝模板以便能夠以下列方式實例化:

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 
wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

我會很感激這方面的幫助。

+5

'std :: function'有什麼問題? –

+0

Boost已經在Boost.Function中有此功能:http://www.boost.org/doc/libs/1_47_0/doc/html/function.html – Dani

+0

http://loki-lib.sourceforge.net/ –

回答

2

改爲使用std::function,或者如果您的編譯器還沒有TR1,則使用Boost實現。這就是說,這是你正在尋找指針成員函數特:

template<typename T, typename C, typename U, typename V> 
class wrapper<T (C::*)(U,V)> 
{ 
private: 
    //typedef pointer to member-function 
    typedef T (C::*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(C c, U a, V b) 
    { 
    return (c.*f)(a,b); 
    } 
}; 

及其實例化這樣的:

wrapper< double(someClass::*)(double, double) > somewrapper; 

你給我的第一個實例是不可能的,但它需要一個龐大的類型擦除的ammount得到它的工作,因爲類的類型不能從構造函數參數推導出來。

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 

第二個可能會工作,稍微修改我的示例代碼,假設您只想使用指向成員函數的實例化它。

wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

假設你想要一個包裝的定義是對於用兼容參數的自由和成員函數可用,你又需要某種類型的擦除,使其工作。實施Boost.Function實際使用不同的技術來避免virtual調用。

+0

感謝您的回覆。我編寫了一個類似於你的類實現的實現,其中類類型作爲模板參數傳遞,但正如你所說,我現在正在查看是否可以編寫單個包裝來涵蓋所有這些場景。在我看來,這樣做不是微不足道的!我會研究類型擦除,我不知道它。 – Omar

2

如果你將此作爲一種編程和學習練習,那很好,但有很多可行的替代方案存在並經過徹底測試。如果使用C++ 11,則可以使用std::function,否則有boost::functionboost::bind

現在假設這是一個學習練習,您將需要爲每個不同參數和返回值創建包裝版本。您還需要涵蓋函數是類成員的情況,並且您可能還想在處理Functor類時處理這種情況。

只要說這是很多工作,很多角落案例,只是爲了複製已經存在的東西。

+0

感謝您的回答。是的,你可能已經制定出來了,這對我來說是一個學習練習。所以我會看看這些實現,看看它們是如何工作的。 – Omar