建设银行网站机构,免费卖货平台,网站本地被劫要怎么做,网站落地页怎么做的目录 一.可调用对象简介
1.什么是可调用对象#xff1f;
2.可调用对象有什么用#xff1f;
二.函数指针和仿函数
1.函数指针
a.函数指针的使用语法
b.函数指针的应用场景
2.仿函数
a.仿函数的基本概念
b.仿函数的优点
三.lambda表达式和function
1.lambda表达式
…目录 一.可调用对象简介
1.什么是可调用对象
2.可调用对象有什么用
二.函数指针和仿函数
1.函数指针
a.函数指针的使用语法
b.函数指针的应用场景
2.仿函数
a.仿函数的基本概念
b.仿函数的优点
三.lambda表达式和function
1.lambda表达式
a.基本语法格式
b.lambda表达式的实战实例
2.function
a.使用方法
b.应用场景和注意事项 一.可调用对象简介
1.什么是可调用对象
可调用对象指的是任何可以像函数那样被调用的实体。这些实体包括普通函数、仿函数对象即重载了 operator() 的类对象或结构体对象、函数指针、lambda表达式、以及C11引入的std::function包装器。
简单来说可调用对象是一个实体我们可以对它传递参数像调用函数一样去调用它。
2.可调用对象有什么用
以std::sort()排序函数为例它用于对元素进行排序通常接受两个或三个参数。前两个参数指定了要排序的范围通常是容器中的一段而第三个参数可选的是一个比较函数或比较函数对象用于明确元素排序的规则如按元素大小排序、按元素字典序排序...等。 再以std::priority_queue() 容器适配器为例它提供了一个基于优先级的队列通常用于管理需要按照优先级顺序处理的元素集合。std::priority_queue() 的构造函数允许你指定其底层容器的类型虽然这通常是隐式的默认为 std::vector、元素的类型以及一个可选的比较函数或函数对象用于确定元素的优先级。 小结可调用对象可以
①作为参数传递如上述的sort()的第三个参数
②在标准库中的使用如上述的优先级队列
③做回调函数即在某个事件发生时由系统或其他代码调用的函数
④自定义比较和排序;
......等。
简单说完了什么是可调用对象和可调用对象的用途后咱们来正式了解可调用对象的具体形式吧它包括函数指针C语言里的那套、仿函数、lambda表达式和包装器。咱们来一一认识~~
二.函数指针和仿函数
1.函数指针
函数指针是指向函数的指针变量它允许我们将函数作为参数传递给其他函数或者将函数地址存储在变量或容器中以供后续调用。
a.函数指针的使用语法
注意函数指针的声明格式返回值类型 (*指针名) (函数参数类型) 通过函数指针调用函数俺直接用函数名调用函数不行吗为啥要再通过一个指针是不是感觉有中脱裤子放P的感觉
暧上面那个例子只是为了将函数指针的使用规则但函数指针真正的应用场景肯定不是这样的。
b.函数指针的应用场景
①函数指针作为参数 ②函数指针做回调函数 函数指针有多种用途比如实现回调函数、在数据结构中存储函数以进行自定义操作等。
2.仿函数
a.仿函数的基本概念
仿函数指的是那些重载了 operator() 的对象或类实例从而使得这些对象或实例可以像函数一样被调用。
例一 例二 仿函数对象可以做实参做sort的第三个参数上述可调用对象简介中有过演示来指定排序规则仿函数也可做类型在优先级队列中明确元素的排序规则。
仿函数的核心在于其重载的 operator() 方法这个方法定义了当仿函数被“调用”时应该执行的操作。由于仿函数实际上是对象因此它们可以包含状态即成员变量这使得它们比传统的函数指针更强大因为函数指针无法直接携带状态信息。
b.仿函数的优点
①仿函数可以包含并维护自己的状态这是函数指针所无法做到的。
②与函数指针相比仿函数提供了更好的类型安全性因为它们的参数和返回类型在编译时就被确定了。
③由于仿函数的本质是一个类对象所以仿函数可以通过继承来扩展功能这是函数指针所不具备的。
④在某些情况下使用仿函数可以使代码更加清晰和易于理解特别是当可调用对象的行为与其数据紧密相关时。
三.lambda表达式和function
Lambda表达式允许我们在代码中定义和使用内联的、匿名的函数对象它们非常适合用于需要小函数的地方。
1.lambda表达式
a.基本语法格式
语法格式[捕捉列表]参数列表mutable - 返回类型 {函数实体};
如auto less [ ] (int x, int y) - bool { return xy; };
调用方式cout less(1 , 2) endl
捕获列表
[]表示以传值的方式捕获所有父作用域中变量和函数包括tihs
[]表示以传引用的方式捕获所有父作用域中变量和函数包括this
例如[x, y] 表示捕获x为值y为引用 或[, z] 表示捕获所有外部变量为值但z为引用或 [, x] 表示捕获所有外部变量为引用但x为值。
[ ] 空捕获表示不捕获任何变量或函数。
lambda的捕捉列表可以捕捉到外界的对象相当于是外界对象的一份拷贝但其默认被const修饰如auto swap [x , y] () { int tmpx; xy; ytmp; }; ×
mutable
而若想改变捕捉的对象则需要使用到mutable如auto swap [x , y] () mutable { int tmpx; xy; ytmp; }; 但此时x和y虽然能在函数定义内改变但其仍是外界对象的一份拷贝其值改变不会影响到外界的对象。
除非是外界对象的引用如auto swap [x , y] () { int tmpx; xy; ytmp; };
参数列表
int x, int y)相当于函数形参是我们调用该可调用对象时传入的参数
- 是固定的语法个数但可以省略bool 相当于函数的返回值类型由于其具体类型可以通过函数实体推导故该类型也可以省略
{ return xy; } 相当于函数实体是可调用对象需要执行的具体功能。
注意范围for的底层是迭代器而lambda的底层是仿函数
lambda对象类型
一个lambda语句对应一个实现有仿函数的类对个lambda对应的类名都不同类名的生成使用了UUID做后缀保证类名不会重复
auto 是可调用对象的类型它是唯一的、未命名的类型这种类型是由编译器根据lambda表达式的捕获列表、参数列表、返回类型以及函数体自动生成的故只能用auto来自动推导或function包装器。
b.lambda表达式的实战实例
示例一捕获父作用域中的局部变量、全局变量和函数体 示例二捕获父作用域中的类对象 2.function
std::function 是一个功能强大的模板类它提供了一种通用的、类型安全的方式来存储和调用任何可调用对象包括普通函数、Lambda表达式、仿函数对象以及成员函数指针。
a.使用方法
定义一个 std::function 实例时需要指定可调用对象的返回类型和参数类型。 function对各类可调用对象的封装 b.应用场景和注意事项
应用场景
①回调函数在需要传递回调函数作为参数的场合function 可以提供一种灵活且类型安全的方式。
②事件处理在基于事件驱动的应用程序中function 可以用于注册事件处理器。
注意事项
空 function 未初始化的 function 是空的调用它会抛出 std::bad_function_call 异常。
多线程function 本身不是线程安全的但如果它所存储的可调用对象是线程安全的那么可以在多个线程中安全地调用它。
性能虽然 function 提供了很大的灵活性但它通常比直接调用函数或Lambda表达式要慢一些因为它涉及到额外的间接调用和类型擦除。