可以帮助程序员确定一个调用表达式的返回类型,主要用于泛型编程和其他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));
//********************************************************************
//绑定成员变量
//********************************************************************
//********************************************************************
}