C++ std::ref————详解

2023-05-16

想学习ref,必须先学习reference_rapper

1、是什么?

ref是个函数模板:
在这里插入图片描述
用来构建一个reference_wrapper对象并返回,该对象拥有传入的elem变量的引用。如果参数本身是一个reference_wrapper类型的对象,则创建该对象的一个副本,并返回。

2、为什么要有ref

std::ref主要在函数式编程(如std::bind)时使用,bind是对参数直接拷贝,无法传入引用(即使你传入的实参是引用类型也不行),故引入std::ref()。使用std::ref可以在模板传参的时候传入引用。

ref能使用reference_wrapper包装好的引用对象代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。

#include <iostream>
#include <functional>
#include<vector>

using namespace std;

std::ref主要是考虑函数式编程(如std::bind)在使用时,是对参数直接拷贝,而不是引用
void f(int& a, int& b, int& c)
{
    cout << "in function a = " << a << "  b = " << b << "  c = " << c << endl;
    cout << "in function a = " << &a << "  b = " << &b << "  c = " << &c << endl;
    a += 1;
    b += 10;
    c += 100;
}

int main() {

    int n1 = 1, n2 = 10, n3 = 100;
    int& r1 = n1;
    int& r2 = n2;

    function<void()> f1 = bind(f, r1, r2, ref(n3));		
    前两个参数即便是引用类型,bind 传入的还是其值的拷贝,第三个参数传入 reference_wrapper 对象,该对象可隐式的转换为值的引用

    f1();
    cout << "out function a = " << n1 << "  b = " << n2 << "  c = " << n3 << endl;
    cout << "out function a = " << &n1 << "  b = " << &n2 << "  c = " << &n3 << endl;
    f1();
    cout << "out function a = " << n1 << "  b = " << n2 << "  c = " << n3 << endl;
    cout << "out function a = " << &n1 << "  b = " << &n2 << "  c = " << &n3 << endl;
    return 0;
}

输出:

in function a = 1  b = 10  c = 100
in function a = 0000006B90EFF710  b = 0000006B90EFF708  c = 0000006B90EFF684
out function a = 1  b = 10  c = 200
out function a = 0000006B90EFF644  b = 0000006B90EFF664  c = 0000006B90EFF684
in function a = 2  b = 20  c = 200
in function a = 0000006B90EFF710  b = 0000006B90EFF708  c = 0000006B90EFF684
out function a = 1  b = 10  c = 300
out function a = 0000006B90EFF644  b = 0000006B90EFF664  c = 0000006B90EFF684

不仅仅是在使用bind时,在使用thread进行编程时,也会发生这样的问题,thread的方法传递引用的时候,必须用ref来进行引用传递,否则就是浅拷贝。

3、ref和引用的区别

首先就是,上面的例子里,使用bind的时候,普通引用和ref引用有区别。

std::ref只是尝试模拟引用传递,并不能真正变成引用,在非模板情况下,std::ref根本没法实现引用传递,只有模板自动推导类型类型隐式转换时,ref能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。

目前我只遇到过类型转换时,ref和普通引用的区别,模板自动推导类型的情况还没遇到过。




参考:http://t.csdn.cn/huxJP

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ std::ref————详解 的相关文章

随机推荐

  • Ubuntu桌面没有图标的解决方案

    我的ubuntu打开的时候就只有鼠标和背景 xff0c 在网上找了一些方法 当桌面啥也没有时 xff0c 按Ctrl 43 Alt 43 T进入终端 xff0c 然后我在网上 找了这个解决方法 xff1a sudo apt span cla
  • Vmmem进程占用大解决办法

    Vmmem xff08 WSL2 xff09 进程占用大解决办法 艹 xff0c 这玩意属实有点过分了 xff0c 办他 xff01 我们先看看docker设置怎么说 哦 xff0c 大概意思就是要通过这个配置文件来配置docker的占用资
  • 2023-03-12 java 子类对父类所拥有的方法的重命名

    例如 xff1a person 里面有个Id方法 public void Id System out println 34 身份证号 xff1a 34 43 id student引用person类 xff0c 现在我们在student里面改
  • Ubuntu2204LTS基础操作详解

    废话不多 说上干货 Ubuntu2204LTS下载链接 xff1a https ubuntu com download 默认使用root用户操作 或者命令前边加 sudo 关闭图形界面 关闭图形界面 xff0c 启用tty终端登录的方法如下
  • 解决Xamarin开发Android项目时的"Could not create the Java Virtual Machine"错误

    如题 xff0c 笔者在编辑Main axml界面时出现 34 Could not create the Java Virtual Machine 34 错误 xff0c 可按以下步骤解决 xff1a 1 运行注册表编辑器 xff1a 开始
  • Centos 7 虚拟机ifconfig或ip addr时,ens33不显示inet地址(已设置NOBOOT为yes)

    在虚拟机中输入ifconfig或ip addr时 xff0c 出现如下情况 xff1a sudo dhclient ens33 sudo ifconfig ens33 依次执行上面两行 xff0c 之后发现ens33中可以显示inet了 本
  • 7---整数反转

    给你一个 32 位的有符号整数 x x x xff0c 返回将 x x x 中的数字部分反转后的结果 如果反转后整数超过 32 位的有符号整数的范围
  • 使用windows远程连接kali的桌面

    使用windows远程连接kali的桌面 kali操作系统需要做的一些配置 安装xrdp span class token function apt span span class token parameter variable y sp
  • Android Studio模拟器出错无法运行的解决办法

    之前在运行Android Studio项目的时候 xff0c 原本用的是AS上安装过的模拟器 xff0c 然后我中途又把夜神模拟器打开也运行了一下 结果当我再次使用AS上的模拟器时 xff0c 模拟器上总是出现一个白色弹窗 xff0c 里面
  • Spring框架

    目录 一 Spring概述 二 Spring入门程序 xff08 理解控制反转IoC xff09 三 依赖注入 xff08 Dependency Injection xff0c DI xff09 3 1 依赖注入的实现方式 一 Spring
  • statement和PreparedStatement的区别

    学习总结转载 xff0c 有改动 xff0c 建议移步原作者 版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https bl
  • Spring环境的搭建和简单使用

    一 为什么使用spring和什么spring 1 xff09 代码中对象间的以来关系特别多 xff0c 代码耦合度比较高 xff0c 为了解决这种问题 xff0c 使用spring框架 2 xff09 spring是一个开源的容器框架 xf
  • Java中&与&&的区别

    Java中 amp 和 amp amp 都是逻辑与 xff0c 需要左右两边同时满足条件才可以得到true的结果 但是 xff0c 它们之间也有区别 xff1a 1 amp amp 也叫短路与 xff0c 当 amp amp 左边的条件不满
  • 关于二叉树的建立(C语言)(链式)

    首先 xff0c 我们得知道二叉树是什么 xff01 xff01 这东西网上一大把 还有 xff0c 二叉树的遍历顺序 xff0c 前序 xff08 根左右 xff09 xff0c 中序 xff08 左根右 xff09 xff0c 后序 x
  • [springMVC学习]1、springmvc设置spring配置文件

    我们给springmvc设置配置文件 xff0c 实际上就是让某个类在tomcat启动时 xff0c 自动的去读取配置文件 xff0c 完成ioc容器的创建 xff0c 完成初始化工作 在spring中 xff0c 我们是手动new出来 x
  • 无法连接 MKS: Login(username/password)incorrect

    升级到Vmware Workstation 12之后 xff0c 客户端能连上虚拟机服务器 xff0c 但却打不开共享的虚拟机 xff0c 提示报错 无法连接 MKS Login username password incorrect 查了
  • 李永乐(一)行列式计算——笔记

    行列式基本性质 一 行列式求值 说明 xff1a 第 i 行元素 乘 第 j 列的代数余子式 之和 61 0 二 转置行列式值不变 引申 xff1a 行有什么性质 xff0c 列就有什么性质 三 两行互换 xff0c 行列式值变号 引申 x
  • 计算机网络——组播地址(多播地址、D类地址)详解——不断完善更新中

    1 是什么 先看这张图 xff0c 组播地址是分类编址的IPv4地址中的D类地址 xff0c 又叫多播地址 xff0c 他的前四位必须是1110 xff0c 所以网络地址的取值范围是224 239 2 这些IP地址用来做什么 224 0 0
  • 线代——猴博士笔记

    求向量组的秩 xff0c 先求极大无关组 xff0c 极大无关组里几个向量 xff0c 秩就是几 什么是极大无关组 xff1f 从一向量组挑出几个向量 xff0c 他们线性无关 xff0c 且原来向量组中任意一个向量加进去 xff0c 又变
  • C++ std::ref————详解

    想学习ref xff0c 必须先学习reference rapper 1 是什么 xff1f ref是个函数模板 xff1a 用来构建一个reference wrapper对象并返回 xff0c 该对象拥有传入的elem变量的引用 如果参数