cpp std::bind std::cref std::ref 实例说明

C++ std::ref与std::cref:引用包装器的核心原理与实战应用 在C++编程中,理解值语义与引用语义是编写高效、正确代码的基础。C++默认采用值语义,对象传递时发生拷贝,这保证了安全性但有时需要传递原始对象的引用。为此,C++11引入了引用包装器(reference wrapper)的概念,它允许将引用作为可拷贝、可存储的值对象处理。这一机制的核心技术价值在于,它使得引用能够在需要值拷贝的上下文中安全传递,例如在函数对象绑定、多线程参数传递和算法回调等场景中。std::ref和std::cref作为工厂函数,分别生成可写和只读的引用包装器std::reference_w 阅读详情

举2个例子说明bind的用法,包含了std::cref 和 std::ref

例子1:

void f(int n1, int n2, int n3, const int& n4, int n5)
{
    std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}

std::cout << "1) argument reordering and pass-by-reference: ";
int n = 7;
auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
n = 10;
f1(1, 2, 1001);

看下bind函数的参数定义
在这里插入图片描述

这里, bind的参数中,f是上面的函数(函数是Callable对象),_2, _1是placeholder的成员,它们分别指 f 函数中的第2个参数n2,第一个参数n1。
std::cref(n)是对n的const引用,它表示函数 f 不能对n的值做修改(如果 f 函数里面有如n++这样的改变n值的操作,是改变不了n的值的),
但是,在 f 外面可以修改n的值。由于是引用,n的变化会反映出来。

比如上面的例子,定义函数 f1 时,n = 7, 最后一个参数n是值参数,在定义时已经固定为7;std::cref(n)是const引用参数,在函数 f 外面 n的改变会影响到它的值。

f1(1,2,1001)这句分两步:
step 1: f1表示函数f, 这里的1, 2, 1001分别对应 f 函数中的n1, n2, n3,可以理解为这3个先保存在n1,n2,n3,待后面用。
step 2: std::bind(f, _2, 42, _1, std::cref(n), n), f 后面的这5个参数表示就表示实际的n1~n5了,
这个_2就是step1中保存在n2中的值,现在把它拿出来,为2;第二个参数为42;
_1是step1中保存在n1的值,把它拿出来,为1;cref(n)为n现在的值=10,最后一个n为定义bind时n的值,为7。

所以 相当于调用了f (2, 42, 1, 10, 7)
它的输出结果为:

argument reordering and pass-by-reference: 2 42 1 10 7

如果想在f 里面也能修改 n 的值,要用std::ref(n)。

例子2:

struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};

std::cout << "5) bind to a pointer to member function: ";
Foo foo;
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
f3(5);

这里的bind中有两个函数参数,它表示把两个指针捆绑在一起,
foo就代表了Foo::print_sum, 这里f3(5) 相当于Foo::print_sum(95, 5),
输出结果:

5) bind to a pointer to member function: 100

你可能想问,我直接像例子1里一样,bind(Foo::print_sum, 95, _1)不就行了,为什么还要引入一个foo?
再看下bind函数的参数定义
在这里插入图片描述
f 必须是 a class of object that has a call operator, 比如a function pointer or a functor object.
如果说非要这样用bind(Foo::print_sum, 95, _1),那也可以,把print_sum函数改为static类型即可(参考)

其他例子请参考官网

【C++知识】 bind函数和ref函数 在ros2这种专门应用泛型编程的开发平台上,会遇到种种BOOST-C++库的应用,如果没有这种库的基础知识,开发将很吃力,建议大家专门学学BOOST C++泛型编程。 阅读详情

相关推荐

C++编程法则365天一天一条(302)std::ref引用包装器

std::ref和std::cref在函数式编程中的作用是非常大的,C++标准库中多次使用到了它们。而std::ref和std::cref事实上是模板函数,返回值是一个std::reference_wrapper对象,而std::reference_wrapper虽然是一个对象,可是他却能展现出和普通引用类似的效果,这点和前一篇文章讲的智能指针如出一辙(事实上标准库大多是这样设计的,这也是运算符重载存在的一个重要意义)。

二进制君 6390

[cpp]c++11学习笔记-std bind

std::bind实现函数绑定功能,类似于给函数起一个别名,通过该对象,可以调用绑定函数。

haily笔记 1081

《大明王朝1566》中,朝廷财政危机无法解决的根源分析

财政困局中的财富最终流向三重黑洞:​皇室挥霍​(如嘉靖炼丹修殿)、特权阶层贪腐​(严党年入百万两盐税)、制度性损耗​(宗室供养、低效官僚)。更深层的“钱”其实是被禁锢在道德化治理的牢笼中——当国家用“黄河长江皆可为用”的权术思维替代制度性改革时,财政危机便成为帝制王朝无法逃脱的宿命。

为了小家奋斗 1966

【cpp笔记-std::bind-占位符】

请注意,如果你不使用 std::ref 或 std::cref,std::bind 将会尝试复制参数,这对于引用类型来说是不可能的,因此会导致编译错误。在这个例子中,add_five 是一个新的可调用对象,它将 add 函数的第一个参数绑定为 5,第二个参数使用占位符 _1 表示,这样在调用 add_five 时,只需要提供一个参数即可。当你使用 std::bind 创建一个新的可调用对象时,你可以将原始函数的某些参数绑定到具体的值上,而对于那些你希望在调用时才提供的参数,你可以使用占位符来代替。

weixin_41766123的博客 1383

c#仿热血江湖

Int32_1 = (int) table.Rows[i]["FLD_初级附魂"],Int32_2 = (int) table.Rows[i]["FLD_中级附魂"],Int32_3 = (int) table.Rows[i]["FLD_是否绑定"],Int32_0 = (int) table.Rows[i]["FLD_进化"],Form1.smethod_1(2, "加载百宝阁物品----没有百宝阁数据");Form1.smethod_1(2, "加载物品商店----没有物品数据");

weixin_42132177的博客 141

人工蜂鸟算法(AHA)详解:原理、实现与应用

人工蜂鸟算法(AHA)是一种受蜂鸟飞行技能和觅食策略启发的新型元启发式优化算法。该算法模拟蜂鸟的全向飞行、记忆能力和觅食行为,通过引导觅食、领地觅食和迁徙觅食三种策略在解空间高效搜索。AHA将优化问题解类比为食物源,蜂鸟作为搜索代理,利用访问表记录访问信息。算法核心包括三种飞行技能建模(全向、对角线和轴向飞行)以及对应的数学公式实现。Python实现展示了种群初始化、适应度计算和觅食行为模拟等关键步骤。AHA以其高效的全局搜索能力、良好收敛性和鲁棒性,在复杂优化问题中表现优异。

qq_42212808的博客 904

C++11——function与bind

function包装器和bind包装器

weixin_68166026的博客 1528

cherry使用MCP协议Streamable HTTP实践

摘要:Streamable HTTP协议是针对传统HTTP+SSE传输方式的改进方案,解决了连接恢复、服务器资源占用和单向通信等问题。该协议基于普通HTTP实现,支持无状态服务器、纯HTTP服务和多轮对话,同时兼容现有基础设施。通过演示展示了服务端和客户端的配置方法,体现了其灵活性和实用性。MCP(多轮对话协议)作为扩展LLM能力的关键技术,代表着未来交互式AI的发展趋势。

全网120W+关注AI拉呱,专注人工智能以及科技前沿! 563

93 CPP11神器之适配器bind

args:绑定参数列表,可以是左值、右值和参数占位符std::placeholders::_n,如果参数不是占位符,缺省为值传递,std:: ref(参数)则为引用传递。std::bind()模板函数是一个通用的函数适配器(绑定器),它用一个可调用对象及其参数,生成一个新的可调用对象,以适应模板。Fx:需要绑定的可调用对象(可以是前两节课介绍的那六种,也可以是function对象)。std::bind()返回std::function的对象。std::bind()的本质是仿函数。

wade1010的专栏 346

【Unity 实用工具篇】 | Unity网格破碎插件 unity-fracture

前面写过一篇Unity中物体破碎效果的插件:【Unity 实用工具篇】 | Unity物体破碎效果 OpenFracture 本文介绍一个另外的工具unity-fracture,也可以实现网格破碎效果,且功能与OpenFracture略有差异。

努力前行,总会成为自己心中的那道光 1万+

【入坑存内计算一键指南】存内计算运算原理:算法优化、存储介质探究

本文探讨了存内计算及其面向的架构优化,尤其侧重于图算法优化和存内计算存储介质。文章介绍了存内计算的概念和意义,着重强调了存内计算解决了内存墙问题,提高了计算效率。针对图算法的优化,提出了基于位运算的创新方法,重塑了单源最短路径算法,并介绍了基于局部重叠度的链路预测算法优化设计。接着,文章详细讨论了存内计算存储介质,特别是非易失性存储器,比较了不同类型存储器的性能,并重点介绍了基于ReRAM的存内计算技术,包括其物理模型和交叉阵列结构。

一键难忘的博客 7062

C++中std是什么意思?(转)

std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的,所以我们要使用标准库中的函数或者对象都要用std来限定。 至于为什么将cout放到名字空间std中,是因为象cout这样的对象在实际操作中或许会有好多个,比如说你自己也可能会不小心定义一个对象叫cout,那么这两个cout对象就会产生冲突。 那么std都是在什么时候使用? 一般来说,std都是要调用C++标准库时使用。比如:使用标准库文件iostream时,要写上std;使用非标准库文件iostream.h,不用写。如图

bj318318的博客 1万+

LLC 谐振转换器中为什么需要 ( L_m )(励磁电感)

在每个模态中,励磁电感 ( L_m )、谐振电感 ( L_r ) 和谐振电容 ( C_r ) 分别承担着储存和释放能量、维持谐振电流和电压波形的任务。Q1和Q2的交替导通确保了这些元件能够在不同的模态下实现能量的有效传输和谐振状态的维持。励磁电感 ( L_m ) 在这一过程中起着不可或缺的作用,确保了电路的高效运行和稳定性。

weixin_43199439的博客 3652

C++11的std::ref、std::cref源码解析

C++11的std::ref、std::cref源码解析1、源码准备2、std::ref和std::cref的作用3、std::ref相关源码解析3.1、std::ref解析3.1、std::reference_wrapper解析3.3、std::remove_cv解析3.4、std::_Reference_wrapper_base解析4、总结 1、源码准备 本文是基于gcc-4.9.0的源代码进行分析,std::ref和std::cref是C++11才加入标准的,所以低版本的gcc源码是没有这两个的,建

游戏行业资深搬砖人员 1万+

【HAL库】STM32CubeMX开发----STM32F407----ETH+LAN8720A+LWIP----ping通

本次实验以芯片为MCU,使用25MHz外部时钟源。以太网PHY层芯片为LAN8720A,由MCU引脚PA8提供时钟。

MQ0522的博客 4841

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

std::ref和std::cref的使用和原理分析

std::reference_wrapper是一个模板类,用于包装引用,使其能够在容器中存储或以引用的形式传递。它提供类似引用的语法,并且可以与标准容器一起使用,因为容器无法直接存储引用。其实使用std::ref时,后台真正起作用的关键类是std::reference_wrapper,它才是真正包装引用的类。#if!

红军不怕远征难,万水千山只等闲 2097

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

std::ref和std::cref使用

std::ref和std::cref 解释 std::ref 用于包装按引用传递的值。 std::cref 用于包装按const引用传递的值。 为什么需要std::ref和std::cref bind()是一个函数模板,它的原理是根据已有的模板,生成一个函数,但是由于bind()不知道生成的函数执行的时候,传递进来的参数是否还有效。所以它选择参数值传递而不是引用传递。如果想引用传...

幻想之渔 3万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

c++11 std::ref,std::cref

和&的区别在于:&是类型说明符,而std::ref,std::cref是函数,需要被包装的到对象的左值引用,或std::reference_wrapper的实例 std::ref 用于包装按引用传递的值。 std::cref 用于包装按const引用传递的值。 之所以会有std::ref,std::cref,主要是考虑c++11中的函数式编程,例如:std::bind...

qq_35558364的博客 1274

std::bind()与std::ref()

文章目录1.std::bind()1. 前言2. std::bind()的作用3.placeholders的作用4.std::bind()使用测试4.1 固定参数、调换顺序4.2 普通函数的参数中有引用类型4.3 普通函数嵌套包装5.包装类成员5.1 成员变量的包装6.总结2.std::ref和std::cref1.为什么需要std::ref和std::cref1.2运行结果:1.3结果分析3.std::ref()和&1.探究过程2.结论 1.std::bind() 1. 前言 不知道大家在做项目写

Destiny_的博客 1810

c++11 std::bind与std::ref、std::cref

直接看代码: #include<iostream> #include<functional> using namespace std; int add(int &a,int &b) { a = 0; b = 0; return a+b; } int main() { int a = 2,b = 3; auto func1 = bi...

李白 854

C++11 std::function, std::bind, std::ref, std::cref

C++11 std::function, std::bind, std::ref, std::cref 转自:http://www.jellythink.com/ std::function 看看这段代码 先来看看下面这两行代码: std::function<void(EventKeyboard::KeyCode, Event*)> onKeyPressed; std::function<void(EventKeyboard::KeyCode, Event*)> onKeyRelea

weixin_44966641的博客 577

【C++11】C++11 std::function, std::bind, std::ref, std::cref

【C++11】C++11 std::function, std::bind, std::ref, std::cref std::function 看看这段代码 先来看看下面这两行代码: std::function<void(EventKeyboard::KeyCode, Event*)> onKeyPressed; std::function<void(EventKeyboard::KeyCode, Event*)> onKeyReleased; 这两行代码是从Cocos2d-x中

qq_43331089的博客 332

C++11 std::ref和std::cref 简介

解释 std::ref 用于包装按引用传递的值。 std::cref 用于包装按const引用传递的值。 #include <iostream> #include <thread> #include <mutex> using namespace std; class A { public: mutable int m_i; //类型...

lobster_wang的博客 1139

C++11中std::reference_wrapper()和std::ref()

std::reference_wrapper是C++11引入的新特性,定义在<functional>头文件中 template< class T > class reference_wrapper; reference_wrapper 将一个引用包装成一个可拷贝的,可分配的对象,是引用的包装器,她通常作为一种将引用存储在标准容器(比如std::vector)中的的机制,因为标准容器通常是无法存储引用的。 reference_wrapper是一个可拷贝构造和可赋值构造的包装器,.

sunlin972913894的博客 2756

C++11 std::ref和引用的区别

std::ref只是尝试模拟引用传递,并不能真正变成引用,在非模板情况下,std::ref根本没法实现引用传递,只有模板自动推导类型时,ref能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。 std::ref主要是考虑函数式编程(如std::bind)在使用时,是对参数直接拷贝,而不是引用 其中代表...

qq_24127015的博客 1585

c++ 中ref关键字的应用

c++ 中 本身可以使用 & 来实现引用 ,那为什么还会出现ref 呢? ref()方法的返回值是reference_wrapper类型,这个类的源码大概的意思就是维持一个指针,并且重载操作符。 ref()能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。 std::ref 用于包装按引用传递的值。 std::cref 用于包装按const引用传递的值。 函数调用,有无ref使用的影响; void fun(

qq_34552942的博客 6845
上一篇: leetcode 21.Merge Two Sorted Lists(merge两个排好序的链表)
下一篇: leetcode 82. Remove Duplicates from Sorted List II (排序链表中删除重复数字II)
蓝羽飞鸟
博客等级 码龄8年 1万+粉丝 727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值