三十行代码说清 std::ref 的用法

int main()
{
    int i = 0;

    /*
        std::ref 把对象包装了一下,通过get方法获取对象的引用,通过修改引用最终修改了对象。
        一些std方法不支持直接传引用,比如std::thread std::async,编译会报错;
        一些方法又把引用 decay 成值了,没有完成初衷,比如 std::bind
    */
    {
        auto wp = std::ref(i);
        int& value = wp.get();
        value = 30;
        std::cout << i << std::endl;//输出30
    }

    {
        std::thread th([&](int& i) {i = 10; }, std::ref(i));
        th.join();
        std::cout << i << std::endl;//输出10
    }

    {
        auto fur = std::async([&](int& i) {i = 20; }, std::ref(i));
        fur.get();
        std::cout << i << std::endl;//输出20
    }

    {
        std::function<void()> bound = std::bind([&](int& i) {i = 40; }, std::ref(i));
        bound();
        std::cout << i << std::endl;//输出40

        //把引用 decay 成值了
        bound = std::bind([&](int& i) {i = 10; }, i);
        std::cout << i << std::endl;//输出40
    }

    return 0;
}

还有 std::cref 区别在于在方法中不能修改值。一些std方法不支持直接传引用,一个原因就是数据要被异步处理,数据正在被处理却在外边被析构的话是不行的。传入std::ref 代表使用者清楚的知道在处理完成之前数据不会被析构,管理数据生命周期的责任在使用者。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值