可以帮助程序员确定一个调用表达式的返回类型,主要用于泛型编程和其他Boost库组件
#include<math.h> #include<iostream> using namespace std; #include<boost/utility/result_of.hpp>//result_of #include<boost/typeof/typeof.hpp>//BOOST_AUTO using namespace boost; template<typename FunType, typename ParamType> typename boost::result_of<FunType(ParamType)>::type CallFunc(FunType fun, ParamType param){return fun(param);} void ResultOf() { typedef double (*LPFN)(double d); LPFN lpfn = sqrt; //获取函数返回值类型方法1 boost::result_of<LPFN(double)>::type result1 = lpfn(1.0); cout << typeid(result1).name() << " result1 = " << result1 << endl; //获取函数返回值类型方法2 BOOST_AUTO(result2, lpfn(4.0)); cout << typeid(result2).name() << " result2 = " << result2 << endl; BOOST_AUTO(result3, CallFunc(lpfn, 9.0)); cout << typeid(result3).name() << " result3 = " << result3 << endl; }//STL和Boost中的算法和函数大量使用了函数对象作为判断式或谓词参数,
//而这些参数都是传值语义,算法或函数在内部保修函数对象的拷贝并使用
//一般情况下传值语义都是可行的,但也有很多特殊情况
//作为参数的函数对象拷贝代价过高(具有复杂的内部状态)
//或者不希望拷贝对象(内部状态不应该被改变),
//甚至拷贝是不可行的(noncopyable、单件)。
//boost.ref应用代理模式,引入对象引用的包装器概念解决了这个问题。
//基本用法:
#include<vector> #include<iostream> #include<iomanip> using namespace std; #include<boost/utility/result_of.hpp> #include<boost/typeof/typeof.hpp> #include<boost/assign.hpp> #include<boost/ref.hpp> using namespace boost; void RefTst01() { int i = 10; reference_wrapper<int> refInt1(i); assert(i == refInt1); (int &)refInt1 = 100; assert(i == 100); reference_wrapper<int> refInt2(refInt1); assert(refInt2.get() == 100); string sTxt; reference_wrapper<string> refString(sTxt); *refString.get_pointer() = "OnlyYou"; cout << ((string&)refString).c_str() << " : " << refString.get().size() << endl << endl; //工厂函数:正向操作 vector<int> oVec(10, 2); BOOST_AUTO(refVec, cref(oVec)); assert(boost::is_reference_wrapper<BOOST_TYPEOF(refVec)>::value); assert(!boost::is_reference_wrapper<BOOST_TYPEOF(oVec)>::value); double d = 1.9999l; BOOST_AUTO(ref1, ref(d)); cout << typeid(ref1).name() << " ref1 = " << ref1 << endl; BOOST_AUTO(ref2, cref(d)); cout << typeid(ref2).name() << " ref2 = " << ref2 << endl << endl; //操作包装:反向操作 BOOST_AUTO(refStr, cref(sTxt)); cout << typeid(BOOST_TYPEOF(refStr)).name() << endl; cout << typeid(boost::unwrap_reference<BOOST_TYPEOF(refStr)>::type).name() << endl; cout << typeid(BOOST_TYPEOF(sTxt)).name() << endl; cout << typeid(boost::unwrap_reference<BOOST_TYPEOF(sTxt)>::type).name() << endl << endl; //直接解开reference_wrapper的包装(如果有的话),返回被包装对象的引用 cout << typeid(BOOST_TYPEOF(refString)).name() << endl; cout << typeid(boost::unwrap_ref(refString)).name() << endl;//解包 } //作为参数的大对象:拷贝代价过高 class CBigCls{ private: int iData; public: CBigCls(){ iData = 65500;} void Disp(){ cout << "In BigCls, Data = " << ++iData << endl;} }; template<typename ClsType> void Print(ClsType obj) { unwrap_ref(obj).Disp(); unwrap_ref(obj).Disp(); } void Ref02() { CBigCls objBig; BOOST_AUTO(refBig, boost::ref(objBig)); objBig.Disp();//65501【初态】 Print(objBig);//65502, 65503【按值传参:拷贝】【objBig内部值不改变】 Print(refBig);//65502, 65503【按引用传参:引用】【objBig内部值改变】 Print(objBig);//65504, 65505【按值传参:拷贝】【objBig内部值不改变】 objBig.Disp();//65504【终态】 } //函数对象:求平方值 struct SSquare{ //必须有typedefresult_type,用来定义返回值类型,否则无法推导 typedef void result_type; void operator()(int num){ cout << num << " * " << num << " = "; num = num*num; cout << num << endl;} }; #include<functional> void RefTst03() { vector<int> oVec = (boost::assign::list_of(1), 2, 3, 4, 5); SSquare oSquare; cout << "按值传参" << endl; for_each(oVec.begin(), oVec.end(), oSquare); for(vector<int>::iterator it = oVec.begin(); it != oVec.end(); it++){ cout << setw(4) << (*it); } cout << endl << endl; cout << "按引用传参" << endl; //for_each(oVec.begin(), oVec.end(), std::ref(oSquare)); for(vector<int>::iterator it = oVec.begin(); it != oVec.end(); it++){ cout << setw(4) << (*it); } cout << endl << endl; }
#include<cstdlib> #include<ctime> #include<string> #include<iostream> using namespace std; #include<boost/utility/result_of.hpp> #include<boost/typeof/typeof.hpp> #include<boost/assign.hpp> #include<boost/ref.hpp> #include<boost/bind.hpp> using namespace boost; int Add2(int x, int y){return (x+y);} int Add3(int x, int y, int z){return (x+y+z);} typedef int (*LPFN2)(int, int); typedef int (*LPFN3)(int, int, int); class CFoo{ public: int Add2(int x, int y){return (x+y);} }; class CPoint{ public: int X, Y; CPoint(int x, int y){X = x; Y = y;} void Disp(){ cout << "Point(" << X << ", " << Y << ")" << endl;} }; void Bind() { LPFN2 lpfn2 = Add2; LPFN3 lpfn3 = Add3; cout << boost::bind(lpfn2, 13, 13)() << endl; cout << boost::bind(lpfn3, 13, 14, 15)() << endl; //绑定普通函数:占位符的使用技巧 //******************************************************************** int x = 1, y = 2, z = 3; cout << boost::bind(Add2, _1, 2)(x) << endl; cout << boost::bind(Add2, _1, _2)(x, y) << endl; cout << boost::bind(Add3, _1, 2, 3)(x) << endl; cout << boost::bind(Add3, _1, _2, 3)(x, y) << endl; cout << boost::bind(Add3, _1, _2, _3)(x, y, z) << endl; cout << boost::bind(Add3, x, _2, z)(x, y) << endl; //_2-------y cout << boost::bind(Add3, x, _3, z)(x, z, y) << endl;//_3-------y //******************************************************************** //绑定成员函数 //******************************************************************** CFoo obj;//类的实例对象 CFoo& ref = obj;//实例对象的引用 CFoo* ptr = &ref;//实例对象的指针 cout << bind(&CFoo::Add2, obj, _1, 20)(10) << endl; cout << bind(&CFoo::Add2, ref, _1, _2)(10, 20) << endl; cout << bind(&CFoo::Add2, ptr, _2, _1)(20, 10) << endl; srand((unsigned)time(NULL));//设置随机数的种子 //使用bind搭配标准算法for_each用来调用容器中所有对象的Disp函数 vector<CPoint> vecPoint; for(int i = 0; i < 10; i++) vecPoint.push_back(CPoint(rand()%100, rand()%100)); for_each(vecPoint.begin(), vecPoint.end(), bind(&CPoint::Disp, _1)); //******************************************************************** //绑定成员变量 //******************************************************************** //******************************************************************** }