支援傳回型別
目前的function_object_ref版本只能支援void傳回型別。我希望能夠讓它支援多種傳回型別,最簡單的方法是添加一個模板參數。請看下面的代碼:
template<typename function_object_type,typename element_type,typename return_type>class function_object_ref{public: explicit function_object_ref(function_object_type & object):object_(&object){ } return_type operator()(element_type e){ return object_->operator()(e); }private: function_object_type* object_;};class compare{public: compare(int x):x_(x){ } bool operator()(int x){ return x_==x; } int x() const{ return x_; }private: int x_;};int main(int argc, char** argv) { compare c(2); function_object_ref<compare,int,bool> wrapper_c(c); vector<int>::iterator itor = std::find_if(v.begin(),v.end(),wrapper_c); cout<<*itor; return 0;}
boost::result_of
上面我的方法雖然解決了問題,但是又引入了一個模板參數。能不能自動推匯出傳回型別,少一個模板參數呢?
即將到來的C++11引入了decltype用於編譯時間推導傳回型別。不過目前在我的gcc工程中還沒有使用C++11,我引入boost::result_of來推導傳回型別。但是result_of卻要求function object要定義傳回型別result_type.所以減少一個模板參數的同時,又在函數對象中增加了一個typedef,樣本如下:
#include <iostream>#include <vector>#include <algorithm>#include <boost/utility/result_of.hpp>using namespace std;template<typename FunctionObjectType, typename ElementType>class FunctionObjectRef {public: explicit FunctionObjectRef(FunctionObjectType & object): object_(&object) { } typedef typename boost::result_of<FunctionObjectType(ElementType)>::type ReturnType; ReturnType operator()(ElementType e) { return object_->operator()(e); }private: FunctionObjectType* object_;};class Compare {public: typedef bool result_type; Compare(int x):x_(x){ } bool operator()(int x){ return x_==x; } int x() const{ return x_; }private: int x_;};int main(int argc, char** argv) { vector<int> v; v.push_back(2); v.push_back(1); Compare c(2); FunctionObjectRef<Compare, int> wrapper_c(c); vector<int>::iterator itor = std::find_if(v.begin(), v.end(), wrapper_c); cout << *itor; return 0;}
感興趣的可以參考boost文檔:http://www.boost.org/doc/libs/1_47_0/libs/utility/utility.htm#result_of
result_of實現非常簡單,就是什麼也不做的模板類:
template<typename F> struct result_of;
當編譯器編譯這行代碼的時候,就能自動推斷出ReturnType
FunctionObjectRef<Compare, int> wrapper_c(c);
typedef typename boost::result_of<FunctionObjectType(ElementType)>::type ReturnType;