boost:ref库

在某些情况下,如在子线程运行一个函数,即使该函数的参数了引用类型,实际上传递时还是要拷贝对象。如果这时希望实际传引用,可以使用 ref 库中定义的引用类型包装器 reference_wrapperref 也被加入到标准库了

#include <boost/ref.hpp>
using namespace boost;

int main()
{
    int x = 10;
    reference_wrapper<int> rw(x);//将x的引用包装为一个对象
    qDebug()<<(x == rw);//true 隐式将reference_wrapper<int>类型转成int类型

    (int &)rw = 100;//显示将rw转成int&类型
    qDebug()<<(x == 100);//true
    qDebug()<<rw.get();//get()获取储存的引用
    qDebug()<<*rw.get_pointer();//get_pointer()获取储存的指针

    reference_wrapper<int> rw2(rw);
    assert(rw2.get() == 100);//true
    *rw.get_pointer() = 200;

    qDebug()<<rw.get();//200
}

工厂函数

reference_wrapper 的名字过长,因而 ref 库提供了两个便捷的工厂函数 ref()和 cref(),可以通过参数类型推导很容易地构造 reference_wrapper 对象。

这两个函数的声明如下:

reference_wrapper <T>                 ref(T& t)

reference_wrapper <T const>        cref (T const& t)

    double x = 2.71828;
    auto rw = cref(x);
    std::cout << typeid(rw).name() << std::endl;

    std::string str;
    auto rws = boost::ref(str);
    std::cout << typeid(rws).name() << std::endl;

    boost::cref(str);

    std::cout << std::sqrt(ref(x)) << std::endl;      //计算平方根

is_reference_wrapper 判断是否被包装

#include <boost/ref.hpp>
using namespace boost;

int main()
{
    std::vector<int> v(10, 2) ;
    auto rw = boost::cref(v);

    assert(is_reference_wrapper<decltype(rw)>::value);
    assert(!is_reference_wrapper<decltype(v)>::value);
}

unwrap_reference 获取真实类型,无论是否被包装

int main()
{
    std::string str;
    auto rws = boost::ref(str);
    std::cout << typeid(unwrap_reference<decltype(rws)>::type).name() << std::endl;
    std::cout << typeid(unwrap_reference<decltype(str)>::type).name() << std::endl;
}

unwrap_ref 解包装,返回被包装对象的引用

int main()
{
    QList<int> list;
    auto rw = boost::ref(list);

    QList<int> & listRef = unwrap_ref(rw);
    listRef.append(120);
    unwrap_ref(rw).append(130);

    qDebug()<<list;//QList(120, 130)
}

与标准库 ref 的区别

最大的区别是标准库的ref可以调用函数对象的操作符。

#include <boost/ref.hpp>
using namespace boost;

struct square
{
    typedef void result_type;
    result_type operator()(int &x)
    {
        x = x * x;
    }
};

int main()
{    
    square sq;
    int x = 5;
    std::ref(sq)(x);        //ok
//    boost::ref(sq)(x);    //error
    std::cout << x << std::endl;
    
    std::vector<int> v = {1,2,3,4,5};
    for_each(v.begin(), v.end(), sq);               //ok
//    for_each(v.begin(), v.end(), std::ref(sq));   //ok
//    for_each(v.begin(), v.end(), boost::ref(sq)); //error
    qDebug()<<v;
}

所以尽量用标准库的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值