代码改变世界

boost::ref

2015-10-09 00:07  youxin  阅读(766)  评论(0编辑  收藏  举报

STL和Boost中的算法和函数大量使用了函数对象作为判断式或谓词参数,而这些参数都是传值语义,算法或函数在内部保修函数对象的拷贝并使用,例如:

#include "stdafx.h"
#include "boost/utility/result_of.hpp"
#include "boost/typeof/typeof.hpp"
#include "boost/assign.hpp"
#include "iostream"
using namespace std;
#include "vector"


int _tmain(int argc, _TCHAR* argv[])
{
struct square
{
typedef void result_type;
void operator()(int& x)
{
x = x * x;
cout << x << endl;
}
};

vector<int> v = (boost::assign::list_of(1), 2, 3, 4, 5);
for_each (v.begin(), v.end(), square());

return 0;
}

一般情况下传值语义都是可行的,但也有很多特殊情况,作为参数的函数对象拷贝代价过高(具有复杂的内部状态),或者不希望拷贝对象(内部状态不应该被改变),甚至拷贝是不可行的(noncopyable、单件)。

boost.ref应用代理模式,引入对象引用的包装器概念解决了这个问题。

 

a、类介绍

ref库定义了一个很小很简单的引用类型的包装器,名字叫reference_wrapper,它的类摘要如下:

template<class T> class reference_wrapper
{ 
public:
    typedef T type;

#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )

    explicit reference_wrapper(T& t): t_(&t) {}

#else

    explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}

#endif

    operator T& () const { return *t_; }

    T& get() const { return *t_; }

    T* get_pointer() const { return t_; }

private:

    T* t_;
};

注意,reference_wrapper的构造函数被声明为explicit,因此必须在创建reference_wrapper对象时就赋值初始化,就像是使用一个引用类型的变量。

reference_wrapper还支持隐式类型转换,可以在需要的语境下返回存储的引用,因此它很像引用类型,能够在任何需要T出现的地方使用reference_wrapper。

 

b、基本用法

看一个例子:

http://blog.csdn.net/zengraoli/article/details/9663057