C++进阶--C++11(2)

C++11第一篇

C++11是C++编程语言的一个版本,于2011年发布。C++11引入了许多新特性,为C++语言提供了更强大和更现代化的编程能力。

可变参数模板

在C++11中,可变参数模板可以定义接受任意数量和类型参数的函数模板或类模板。它可以表示0到任意个数,任意类型的参数。通过使用(…)来声明可变参数,省略号后面的参数被称为参数包。

下面是可变参数的函数模板:

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}

在这里插入图片描述

//展开函数的终止
template<class T>
void Showlist(const T& t)
{cout << t << endl;
}
//可变模板参数
template<class T,class ...Args>
void Showlist(T value, Args... args)
{cout << value << " ";Showlist(args...);
}int main()
{Showlist(1);Showlist(1, 'A');Showlist(1, 'A', std::string("sort"));return 0;
}

在这里插入图片描述

emplace_back()

在这里插入图片描述

测试与push_back()的区别:

int main()
{std::list<fnc::string> lt1;fnc::string s1("xxxx");lt1.push_back(s1);lt1.push_back(move(s1));cout << "=============================================" << endl;fnc::string s2("xxxx");lt1.emplace_back(s2);lt1.emplace_back(move(s2));cout << "=============================================" << endl;lt1.push_back("xxxx");lt1.emplace_back("xxxx");cout << "=============================================" << endl;std::list<pair<fnc::string, fnc::string>> lt2;pair<fnc::string, fnc::string> kv1("xxxx", "yyyy");lt2.push_back(kv1);lt2.push_back(move(kv1));cout << "=============================================" << endl;pair<fnc::string, fnc::string> kv2("xxxx", "yyyy");lt2.emplace_back(kv2);lt2.emplace_back(move(kv2));cout << "=============================================" << endl;lt2.emplace_back("xxxx", "yyyy");cout << "=============================================" << endl;return 0;
}

在这里插入图片描述
再测试:

class Date
{
public:Date(int year=1900, int month=1, int day=1):_year(year), _month(month), _day(day){cout << "Date(int year, int month, int day)" << endl;}Date(const Date& d):_year(d._year), _month(d._month), _day(d._day){cout << "Date(const Date& d)" << endl;}
private:int _year;int _month;int _day;
};int main()
{//直接在参数中插入std::list<Date> lt1;lt1.push_back({ 2024,3,30 });lt1.emplace_back(2024, 3, 30);//直接插入已有的对象cout << endl;Date d1(2023, 1, 1);lt1.push_back(d1);lt1.emplace_back(d1);//插入匿名对象cout << endl;lt1.push_back(Date(2023, 1, 1));lt1.emplace_back(Date(2023, 1, 1));return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

lambda

在这里插入图片描述

lambda语法表达式

[capture-list] (parameters) mutable -> return-type { statement}

  • [capture-list]:捕捉列表:位于lambda表达式最前位置,编译器通过[]来进行判断,能捕捉上下文中的变量给lambda表达式使用;
  • (parameters):参数列表,与函数的参数列表使用一致,如果没有参数的话,可省略使用;
  • mutable:默认情况下,lambda函数是一个const函数,使用mutable可以取消const性。使用该单词,不可省略参数列表。
  • -> return-type :返回值类型,用于声明函数的返回值类型,没有返回值进行省略;一般有返回值也可以省略,通过编译器进行推导。
  • {statement}:函数主体,除了使用参数列表的参数,也可使用捕捉列表的参数。

接下来看lambda的简单使用:

int main()
{//auto add = [](int a, int b)->int{return a + b; };auto add = [](int a, int b) {return a + b; };cout << add(1, 21) << endl;auto swap = [](int& a, int& b){int tmp = a;a = b;b = tmp;};int x = 2, y = 22;swap(x, y);cout << x << " " << y << endl;auto func = []() {cout << "lambda" << endl; };func();return 0;
}

在这里插入图片描述

对上面sort的改装:
在这里插入图片描述

捕捉列表

#include<algorithm>
int main()
{int x = 1, y = 2;auto swap = [&x, &y]()mutable{int tmp = x;x = y;y = tmp;};swap();cout << x << " " << y << endl;int m = 3, n = 4;//传值捕捉'=':捕捉当前域的所有对象auto func1 = [=](){return m * n - x - y;};cout << func1() << endl;//传引用捕捉:捕捉当前域所有对象auto func2 = [&](){x++;y++;return m * n - x - y;};cout << func2() << endl;//x:2,y:3,m:3,n:4//对n传值捕捉,其他的传引用捕捉auto func3 = [&, n](){x++;y++;m++;//n++;错误return m * n - x - y;};cout << func3() << endl;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

lambda底层

class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}
private:double _rate;
};int main()
{//函数对象/仿函数double rate = 0.49;Rate r1(rate);r1(10000, 2);// lambdaauto r2 = [=](double monty, int year)->double {return monty * rate * year;};r2(10000, 2);auto f1 = [] {cout << "hello world" << endl; };auto f2 = [] {cout << "hello world" << endl; };f1();f2();return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

包装器

为什么要有包装器?

template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}double f(double i)
{return i / 2;
}struct Functor
{double operator()(double d){return d / 3;}
};int main()
{// 函数名cout << useF(f, 11.11) << endl;// 函数对象cout << useF(Functor(), 11.11) << endl;// lamber表达式cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;return 0;
}

在这里插入图片描述

类模板:

template <class T> function; // undefinedtemplate <class Ret, class... Args>
class function<Ret(Args...)>;
  • Ret:表示调用函数的返回类型;
  • Args:表示函数的参数列表的参数;

简单对上面例题使用

#include<functional>int main()
{// 函数指针function<double(double)> fc1 = f;fc1(11.11);cout << useF(fc1, 11.11) << endl;// 函数对象function<double(double)> fc2 = Functor();fc2(11.11);cout << useF(fc2, 11.11) << endl;// lambda表达式function<double(double)> fc3 = [](double d)->double { return d / 4; };fc3(11.11);cout << useF(fc3, 11.11) << endl;return 0;
}

在这里插入图片描述

类成员函数

int f(int a, int b)
{return a + b;
}class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};int main()
{// 普通函数function<int(int, int)> fc1 = f;cout << fc1(1, 1) << endl;// 静态成员函数function<int(int, int)> fc2 = &Plus::plusi;cout << fc2(1, 1) << endl;// 非静态成员函数// 非静态成员函数需要对象的指针或者对象去进行调用function<double(Plus, double, double)> fc3 = &Plus::plusd;cout << fc3(Plus(), 1, 1) << endl;return 0;
}

在这里插入图片描述

bind

在C++中,bind是一个函数模板,位于<functional>头文件中,用于创建函数对象(也称为函数绑定器),可以将参数绑定到函数调用中。

bind函数的语法如下:

template< class Fn, class... Args >
bind( Fn&& fn, Args&&... args );

其中,Fn表示要绑定的函数或可调用对象,Args表示要绑定的参数。

使用bind函数可以实现函数的延迟调用、固定部分参数等功能。

简单使用

int Sub(int a, int b)
{return a - b;
}class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a - b;}
};int main()
{// 调整参数顺序int x = 10, y = 20;cout << Sub(x, y) << endl;auto f1 = bind(Sub, placeholders::_2, placeholders::_1);cout << f1(x, y) << endl;function<double(Plus, double, double)> fc3 = &Plus::plusd;cout << fc3(Plus(), 1, 1) << endl;// 调整参数的个数// 某些参数绑死function<double(double, double)> fc4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);cout << fc4(2, 3) << endl;function<double(double)> fc5 = bind(&Plus::plusd, Plus(), placeholders::_1, 20);cout << fc5(2) << endl;return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/299218.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++之类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1访问限定符 4.2 类的两种定义方式 第一种&#xff1a; 第二种&#xff1a; 4.3封装 5.类的实例化 6.类对象模型 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;…

【Claude 3】This organization has been disabled.此组织已被禁用。(Claude无法对话的原因和解决办法)

Claude对话提示 This organization has been disabled.此组织已被禁用。 This organization has been disabled.此组织已被禁用。 This organization has been disabled.此组织已被禁用。 问题截图 问题原因 出现该页面&#xff0c;表示您的账户已经无法使用&#xff0c;可能…

SQL语言

一、DDL数据库定义语言 1、登录mySQL mysql -u"用户名" -p"密码" -h"登录地址 -h&#xff1a;默认为本机 示例&#xff1a; 2、查看当前存在的数据库 show databases; 示例&#xff1a; 3、创建数据库database create…

约数与倍数-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第45讲。 约数与倍数&#…

非关系型数据库——Redis基本操作

目录 一、Redis数据库常用命令 1.Set——存放数据 2.Get——获取数据 3.Keys——获取符合条件的键值 4.Exists——判断键值是否存在 5.Del——删除指定键值 6.Type——获取键值对应的类型 7.Rename——对已有键值重命名&#xff08;覆盖&#xff09; 8.Renamenx——对…

更高效、更简洁的 SQL 语句编写丨DolphinDB 基于宏变量的元编程模式详解

元编程&#xff08;Metaprogramming&#xff09;指在程序运行时操作或者创建程序的一种编程技术&#xff0c;简而言之就是使用代码编写代码。通过元编程将原本静态的代码通过动态的脚本生成&#xff0c;使程序员可以创建更加灵活的代码以提升编程效率。 在 DolphinDB 中&#…

【智能算法】随机分形搜索算法(SFS)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2015年&#xff0c;Salimi等人受到分形的扩散性质启发&#xff0c;提出了随机分形搜索算法&#xff08;Stochastic Fractal Search &#xff0c;SFS&#xff09;。 2.算法原理 2.1算法思想 SFS通…

《QT实用小工具·十一》Echart图表JS交互之仪表盘

1、概述 源码放在文章末尾 该项目为Echart图表JS交互之炫酷的仪表盘&#xff0c;可以用鼠标实时改变仪表盘的读数。 下面为demo演示&#xff1a; 该项目部分代码如下&#xff1a; #include "widget.h" #include "ui_widget.h" #include "qurl.h&q…

鸿蒙实战开发-如何使用Stage模型卡片

介绍 本示例展示了Stage模型卡片提供方的创建与使用。 用到了卡片扩展模块接口&#xff0c;ohos.app.form.FormExtensionAbility 。 卡片信息和状态等相关类型和枚举接口&#xff0c;ohos.app.form.formInfo 。 卡片提供方相关接口的能力接口&#xff0c;ohos.app.form.for…

[VulnHub靶机渗透] pWnOS 2.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

Android 的网络加载

发起网络请求的过程 当用户在应用程序中输入网址或关键字时&#xff0c;应用程序会发起网络请求。这个过程大致如下&#xff1a; 应用程序将请求发送到服务器&#xff0c;服务器返回响应数据。应用程序接收到响应数据后&#xff0c;将其转换为应用程序可识别的数据格式。应用…

Mybatis--TypeHandler使用手册

TypeHandler使用手册 场景&#xff1a;想保存user时 teacher自动转String &#xff0c;不想每次保存都要手动去转String&#xff1b;从DB查询出来时&#xff0c;也要自动帮我们转换成Java对象 Teacher Data public class User {private Integer id;private String name;priva…

C++设计模式:策略模式(二)

1、定义与动机 定义一系列算法&#xff0c;把它们一个个封装起来&#xff0c;并且使它们可互相替换&#xff08;变化&#xff09;&#xff0c;该模式使得算法可独立于使用它的客户程序&#xff08;稳定&#xff09;而变化&#xff08;扩展&#xff0c;子类化&#xff09; 在软…

web安全学习笔记(6)

记一下第十节课的内容。 一.PHP语言中的if else判断 语法和c语言中非常类似&#xff0c;不再赘述&#xff0c;也可以使用if...elseif...elseif...else 1.True和False 2.&#xff0c;和 一个等号是赋值 两个等号是比较 三个等号是全等&#xff08;内容相等&#xff0c;数…

OpenHarmony开发-系统烧录

本文详细介绍了烧录OpenHarmony系统到开发板的操作流程。从基础的硬件准备和软件环境设置入手&#xff0c;详细说明了如何配置开发环境、构建系统镜像等过程&#xff0c;详细描述了烧录过程中的关键步骤&#xff0c;以及如何使用专用工具将OpenHarmony系统镜像传输到开发板。同…

第十四届蓝桥杯大赛软件赛省赛

第十四届蓝桥杯大赛软件赛省赛 2.日期统计 小蓝现在有一个长度为 100 的数组&#xff0c;数组中的每个元素的值都在 0 到 9 的范围之内。 数组中的元素从左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 …

PyQt6实战6--高亮

PyQt6实战3--sql查询器-CSDN博客 在sql查询器的基础上添加了sql语法的高亮 运行效果&#xff1a; 代码&#xff1a; 只需要在原来的代码上添加一行 rightTopLayout QVBoxLayout()rightTopLayout.addWidget(QLabel("输入sql:"))self.sql QTextEdit() #加一行高亮&…

【踩坑日记】因不同系统换行符不同导致的文本读取结果不同的问题

文章目录 1 问题现象描述2 解决过程&#xff08;点击直接跳到解决方法&#xff09;3 原因解释4 如何避免踩坑4.1 格式转换4.2 格式查看 1 问题现象描述 起因是群友问了这么一个问题 确实很奇怪&#xff0c;按理说第二个printf不会完全不输出&#xff0c;于是想到&#xff0c;…

多线程学习-线程池

目录 1.线程池的作用 2.线程池的实现 3.自定义创建线程池 1.线程池的作用 当我们使用Thread的实现类来创建线程并调用start运行线程时&#xff0c;这个线程只会使用一次并且执行的任务是固定的&#xff0c;等run方法中的代码执行完之后这个线程就会变成垃圾等待被回收掉。如…

7.二叉树的遍历方式及二叉树习题

4.二叉树链式结构的实现 二叉树是&#xff1a; 空树 非空&#xff1a;根节点&#xff0c;根节点的左子树、根节点的右子树组成的。 4.1二叉树的遍历 4.2.1 前序、中序以及后序遍历 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前…