Boost.result_of、ref、bind详细用法示例

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

	//绑定成员变量
	//********************************************************************
	//********************************************************************
}


猜你喜欢

转载自blog.csdn.net/knightonhourse/article/details/80266985