徐州市建设银行网站,蓝色脚手架织梦企业网站模板,网站建设与管理案例教程第三版课后答案,什么是网站建设与维护【STL十四】函数对象#xff08;function object#xff09;_仿函数#xff08;functor#xff09;——lambda表达式 一、函数对象#xff08;function object#xff09;二、函数对象优点三、分类四、头文件五、用户定义函数对象demo六、std::内建函数对象1、 算术运算函… 【STL十四】函数对象function object_仿函数functor——lambda表达式 一、函数对象function object二、函数对象优点三、分类四、头文件五、用户定义函数对象demo六、std::内建函数对象1、 算术运算函数对象2、比较3、逻辑运算4、位运算 七、lambda表达式1、简介2、作用3、定义4、最简单的demo5、标准用法6、变量捕获capture clause) 一、函数对象function object
定义定义了一个operator的对象就叫函数对象function object。函数对象又被叫做仿函数functor。
注意
函数对象是一个类or结构体、模板类不是一个函数。函数对象重载“”操作符使得类可以像函数那样调用。 安装参数分 如果函数对象有一个参数叫一元函数对象。 如果函数对象有二个参数叫二元函数对象。 如果函数对象有三个参数叫多元函数对象。 二、函数对象优点
函数对象通常不定义构造函数和析构函数所以在构造和析构不会发生问题函数对象可以有自己的状态超出了普通函数的概念模板函数对象使得函数对象具有通用性。
三、分类
用户定义函数对象std::内置函数对象lambda表达式
四、头文件
用户自己定义的函数无头文件std内建函数对象 头文件如下
// 内置函数对象
#includefunctional五、用户定义函数对象demo
Print就是函数对象Print()(“HELLO WORLD”);//匿名函数对象
#include iostream
//
using namespace std;class Print
{
public:void operator()(const char str[]){cout str endl;}
};int main() {Print ob;ob(hello world);Print()(HELLO WORLD);//匿名函数对象}输出 hello world HELLO WORLD 函数对象可以有自己的状态? demo
#include iostream
//#includefunctional
using namespace std;class Print
{
public:void operator()(const char str[]){cout str endl;m_sum;}int m_sum 0;
};int main() {Print ob;ob(hello world);ob(hello jx);cout ob.m_sum endl;}输出 hello world hello jx 2 当然以上你可以写成模板or同时重载int类型的都是可以的 重载int类型的
#include iostream
//#includefunctional
using namespace std;struct Print
{
public:void operator()(const char str[]){cout str endl;}void operator()(int num){cout num endl;}
};int main() {Print ob;ob(hello world);Print()(HELLO WORLD);ob(110);}模板函数对象使得含对象具有通用性? 模板
#include iostream
#includestring
using namespace std;templatetypename T
class Print
{
public:void operator()(T temp){cout temp endl;m_sum;}int m_sum 0;
};int main() {Printstring ob;ob(hello world);ob(hello jx);cout ob.m_sum endl;Printint ob2;ob2(123);ob2(123);
}
输出 hello world hello jx 2 123 123 六、std::内建函数对象
stl内建了一些函数对象分为算术运算、比较、逻辑运算、位运算其实这些内建函数对象都是配合容器和算法使用的但是我们还没有讲解郭算法所以做个不设计算法的简单的demo.
1、 算术运算函数对象
1.1、分类 1.2、demo
#include iostream
#includefunctional
using namespace std;int main() {std::plusint add;cout add(2, 3) add(2, 3) endl; //23 5std::minusint sub;cout sub(2, 3) sub(2, 3) endl; //2-3 -1std::multipliesint mul;cout mul(2, 3) mul(2, 3) endl; //2*3 6std::dividesint div;cout div(2, 3) div(2, 3) endl; //2/3 0std::modulusint mod;cout mod(2, 3) mod(2, 3) endl; //2%3 2std::negateint neg;cout neg(2) neg(2) endl; //neg(2) -2 }
输出 add(2, 3) 5 sub(2, 3) -1 mul(2, 3) 6 div(2, 3) 0 mod(2, 3) 2 neg(2) -2 2、比较
2.1、分类 2.2、demo
#include iostream
#includefunctional
using namespace std;int main() {std::equal_toint ob1;cout ob1(1, 2) ob1(1, 2) endl;std::not_equal_toint ob2;cout ob2(1, 2) ob2(1, 2) endl;std::greaterint ob3;cout ob3(1, 2) ob3(1, 2) endl;std::lessint ob4;cout ob4(1, 2) ob4(1, 2) endl;std::greater_equalint ob5;cout ob5(1, 2) ob5(1, 2) endl;std::less_equalint ob6;cout ob6(1, 2) ob6(1, 2) endl;
}输出 ob1(1, 2) 0 ob2(1, 2) 1 ob3(1, 2) 0 ob4(1, 2) 1 ob5(1, 2) 0 ob6(1, 2) 1 3、逻辑运算
3.1、分类 3.2、demo
#include iostream
#includefunctional
using namespace std;int main() {std::logical_andbool l_and;cout l_and(1, 0) l_and(1, 0) endl;std::logical_orint l_or;cout l_or(1, 0) l_or(1, 0) endl; std::logical_notint l_not;cout l_not(2) l_not(2) endl;
}输出 l_and(1, 0) 0 l_or(1, 0) 1 l_not(2) 0 4、位运算
4.1、分类 demo 1、“与” 运算:只有两个位都是1的时候结果才是1否则是0;如1111000100002、“或” 运算|:只要有一个是1结果就是1。如1|010|111|110|003、“异或” 运算^:相同为0不同为10|000|111|011|104、取反运算~就是0110 #include iostream
#includefunctional
using namespace std;int main() {std::bit_andint b_and;cout b_and(1, 2) b_and(1, 2) endl;std::bit_orint b_or;cout b_or(1, 2) b_or(1, 2) endl;std::bit_xorint b_xor;cout b_xor(2,3) b_xor(2,3) endl;std::bit_notbool b_not;cout b_not(1) b_not(1) endl;
}
输出 b_and(1, 2) 0 b_or(1, 2) 3 b_xor(2,3) 1 b_not(1) 1 bit_not有问题因为bool的取反应该是0但是输出是1原因未知
七、lambda表达式 使用 STL 时往往会大量用到函数对象为此要编写很多函数对象类。有的函数对象类只用来定义了一个对象而且这个对象也只使用了一次编写这样的函数对象类就有点浪费。 而且定义函数对象类的地方和使用函数对象的地方可能相隔较远看到函数对象想要查看其 operator() 成员函数到底是做什么的也会比较麻烦。 对于只使用一次的函数对象类能否直接在使用它的地方定义呢Lambda 表达式能够解决这个问题。使用 Lambda 表达式可以减少程序中函数对象类的数量使得程序更加优雅。
1、简介
lambda expressions lambda表达式也叫闭包——Colsure)lambda表达式也是匿名函数对象lambda表达式也是一种仿函数、
2、作用
很方便的定义函数、并被别的函数调用。
3、定义
Lambda 表达式的定义形式如下 []中括号里面是一下捕获变量或者为空。 [捕获变量] (参数表) - 返回值类型
{函数主体
}auto f[](int a, int b) -int
{
return ab;
};“捕获变量”可以是或表示{}中用到的、定义在{}外面的变量在{}中是否允许被改变。表示不允许表示允许。当然在{}中也可以不使用定义在外面的变量。“- 返回值类型”可以省略。
4、最简单的demo
#include iostream
#includevector
#includefunctional
using namespace std;int main() {auto f [](int a, int b){return a b;};cout f(2, 3);
}输出 1 5、标准用法
#include iostream
#includevector
#includefunctional
using namespace std;int main() {// 定义lambda表达式不使用变量捕获auto f [](int a, int b) -int{return a b;};cout f(1, 2) endl;
}输出 3 6、变量捕获capture clause)
#include iostream
#includevector
#includefunctional
using namespace std;int main() {int M 10;int N 3;auto f [M, N](int a) -int{M 20;return N*a;};cout f(3) endl;cout M endl;
}输出 9 20 变量捕获就是方括号中的部分让我们的匿名函数可以访问、甚至修改函数外部的变量。如果是空表示不捕获任何变量。[M]——如果变量前有引用则是按引用捕获——可以修改外围变量的值。[M]——如果变量前没引用则是按值捕获——不可以修改外围变量的值。[]——只写引用按照引用捕获所有的封闭范围中的变量[]——只写等号所有变量都按值捕获[, M]——单独制定一些变量按照值捕获其他变量按照引用捕获[this]——如果在某个class中使用匿名函数可以使用this捕获当前实例的指针。c17后还可以使用[*this]按值捕获该实例。c14后可以在捕获语句中定义新的变量并初始化。这些变量无需出现在匿名函数外围环境中
auto f [M, N, k5](int a) -int{M 20;return N*a*k;};c14后参数列表支持auto类型
[](auto a, auto b){return ab;}参考 1、C STL 容器库 中文文档 2、STL教程C STL快速入门 3、https://www.apiref.com/cpp-zh/cpp/header.html 4、https://en.cppreference.com/w/cpp/container 5、哔哩哔哩_HexUp_清晰易懂现代C最好用特性之一Lambda表达式用法详解 6、WIKI教程_C 标准库_C Library - iterator