【C++】C++11 篇二

【C++】C++11 篇二

    • 前言
      • 移动构造函数
      • 移动赋值运算符重载
      • 类成员变量初始化 (缺省值出自C++11
      • 强制生成默认函数的关键字default:
      • 禁止生成默认函数的关键字delete:
      • 继承和多态中的final与override关键字(出自C++11
    • 可变参数模板
      • 递归函数方式展开参数包
      • 逗号表达式展开参数包
    • STL容器中的empalce相关接口函数
    • lambda表达式
      • 实例
      • lambda表达式语法
        • 实例:
        • lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }
        • 捕获列表说明
        • 函数对象(仿函数)与lambda表达式

前言

C++98的6个默认成员函数:

  1. 构造函数
  2. 析构函数
  3. 拷贝构造函数
  4. 拷贝赋值重载
  5. 取地址重载 //用处不大
  6. const 取地址重载 //用处不大

C++111 新增了两个:移动构造函数移动赋值运算符重载

移动构造函数

如果没有自己实现移动构造函数,且析构函数 、拷贝构造、拷贝赋值重载都没有实现
那么编译器会自动生成一个默认移动构造。
默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,
自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造

移动赋值运算符重载

(默认移动赋值跟上面移动构造完全类似,把移动构造函数替换为移动赋值运算符重载即可)

类成员变量初始化 (缺省值出自C++11

C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化

强制生成默认函数的关键字default:

提供了拷贝构造,就不会生成移动构造了,使用default关键字强制生成

Person(Person&& p) = default;

禁止生成默认函数的关键字delete:

Person(Person&& p) = delete;

继承和多态中的final与override关键字(出自C++11

可变参数模板

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args…args,这个参数包中可以包含0到任意个模板参数
//C语言的printf scanf函数的参数就是可变的
//语法不支持使用args[i]这样方式获取可变参数

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;
}

逗号表达式展开参数包

//由于是逗号表达式,在创建数组的过程中会先执行逗号表达式前面的部分printarg(args)
打印出参数
再得到逗号表达式的结果0
//通过初始化列表来初始化一个变长数组, {(printarg(args), 0)…}将会展开成((printarg(arg1),0),
(printarg(arg2),0), (printarg(arg3),0), etc… ),最终会创建一个元素值都为0的数组int arr[sizeof…(Args)]。

template <class T>
void PrintArg(T t)
{cout << t << " ";
}
//展开函数
template <class ...Args>
void ShowList(Args... args)
{int arr[] = { (PrintArg(args), 0)... };cout << endl;
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

STL容器中的empalce相关接口函数

template <class… Args>
void emplace_back (Args&&… args);

emplace系列的接口,支持模板的可变参数,并且万能引用。那么相对insert和
emplace系列接口的优势到底在哪里呢?

int main()
{std::list< std::pair<int, char> > mylist;// emplace_back支持可变参数,拿到构建pair对象的参数后自己去创建对象// 那么在这里我们可以看到除了用法上,和push_back没什么太大的区别mylist.emplace_back(10, 'a');//避免了临时对象的创建和拷贝 / 移动,效率更高mylist.emplace_back(make_pair(30, 'c'));//相当于退化为了 push_back() 的效果。//:push_back() 必须先有一个完整的对象(可能是临时对象),再将其放入容器,比直接构造多一次拷贝 / 移动操作(在优化前)。mylist.push_back(make_pair(40, 'd'));mylist.push_back({ 50, 'e' });//只是用初始化列表简化了对象的创建,仍会产生临时对象(调用构造函数)for (auto e : mylist)cout << e.first << ":" << e.second << endl;return 0;
}

lambda表达式

实例

#include <algorithm>
#include <functional>
int main()
{
int array[] = {4,1,8,5,3,7,0,9,2,6};
// 默认升序
std::sort(array, array+sizeof(array)/sizeof(array[0]));
// 降序greater<int>()依赖#include <functional>
std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
return 0;
}

待排序元素为自定义类型,需要用户定义排序时的比较规则,仿函数

struct Goods
{string _name;  // 名字double _price; // 价格int _evaluate; // 评价Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};
struct ComparePriceLess
{bool operator()(const Goods& gl, const Goods& gr){return gl._price < gr._price;}
};
struct ComparePriceGreater
{bool operator()(const Goods& gl, const Goods& gr){return gl._price > gr._price;}
};
int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());
}

lambda表达式(匿名函数),其实底层就是仿函数

int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 
3 }, { "菠萝", 1.5, 4 } };sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price < g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price > g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate < g2._evaluate; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate > g2._evaluate; });
}

lambda表达式语法

实例:
int main()
{// 最简单的lambda表达式, 该lambda表达式没有任何意义[]{}; // 省略参数列表和返回值类型,返回值类型由编译器推导为intint a = 3, b = 4;[=]{return a + 3; }; // 省略了返回值类型,无返回值类型auto fun1 = [&](int c){b = a + c; }; fun1(10)cout<<a<<" "<<b<<endl;// 各部分都很完善的lambda函数auto fun2 = [=, &b](int c)->int{return b += a+ c; }; cout<<fun2(10)<<endl;// 复制捕捉xint x = 10;auto add_x = [x](int a) mutable { x *= 2; return a + x; }; cout << add_x(10) << endl; return 0;
}

lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量

lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }
  1. [capture-list] : 捕捉列表,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉上下文中的变量供lambda
    函数使用。
  2. (parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以
    连同()一起省略
  3. mutable:默认情况下,lambda函数总是一个const函数mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
  4. returntype:返回值类型可省略,由编译器对返回类型进行推导。
  5. {statement}:函数体。在该函数体内,可以使用其参数外,还可使用捕获
    到的变量。

注意: 在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为
空。因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情

捕获列表说明

捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。
[var]:表示值传递方式捕捉变量var
[=]:表示值传递方式捕获所有父作用域中的变量**(包括this)**
[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针

注意:
a. 父作用域指包含lambda函数的语句块
b. 语法上捕捉列表可由多个捕捉项组成,并以逗号分割。
比如:[=,&a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量
[&,a,this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量
c. 捕捉列表不允许变量重复传递,否则就会导致编译错误。
比如:[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复
d. 在块作用域以外的lambda函数捕捉列表必须为空
e. 在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都会导致编译报错。
f. lambda表达式之间不能相互赋值,类型不同,其类型构成含有uuid,通用唯一标识符

void (*PF)();
int main()
{auto f1 = []{cout << "hello world" << endl; };auto f2 = []{cout << "hello world" << endl; };//f1 = f2;   //类型不同,不可赋值// 允许使用一个lambda表达式拷贝构造一个新的副本auto f3(f2);//默认包含 operator() 重载(用于调用 Lambda 逻辑)f3();// 可以将lambda表达式赋值给相同类型的函数指针PF = f2;PF();return 0;
}

小结

  1. Lambda 表达式会被编译器隐式转换为一个匿名的函数对象类型
  2. 是编译器自动生成的、唯一的类类型
  3. 默认包含 operator() 重载(用于调用 Lambda 逻辑)
  4. 对于没有捕获变量的 Lambda,可隐式转换为函数指针;有捕获变量的 Lambda 则不能
函数对象(仿函数)与lambda表达式

函数对象,又称为仿函数,即可以像函数一样使用的对象,就是在类中重载了operator()运算符类对象

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;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);//仅仅调构造cout << r1(10000, 2);//仅仅调operator()cout << endl;// lamber//r1 虽然是外部变量,但未在 Lambda 表达式中使用,因此不会被捕捉auto r2 = [=](double monty, int year)->double {return monty * rate * year; };cout << r2(10000, 2);return 0;
}

函数对象将rate作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可
以直接将该变量捕获到。

在这里插入图片描述

在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,
即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()。

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

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

相关文章

构建Python环境的几种工具

本文主要介绍如何构建Python环境来处理不同的工作。 1.常用的构建Python环境的工具 ①venv(内置模块):Python 3.3 内置标准库模块&#xff0c;无需额外安装。 ②virtualenv:venv的前身&#xff0c;功能更强大且支持旧版Python。 ③conda:来自 Anaconda 或 Miniconda。不仅能…

c#项目编译时外部依赖文件的同步问题

很多场景因为资源文件太多或太大无法放到资源里面或者是依赖的dll文件&#xff0c;需要编译时同步到bin\debug或bin\release下的&#xff0c;这里面要修改工程文件代码实现。 比如&#xff0c;我把这个项目依赖的dll和附加文件放到ref_dll文件夹里面&#xff0c;希望编译的时候…

数学建模常用算法-模拟退火算法

一、模拟退火算法模拟退火的灵感来源于物理中的 “退火过程”—— 将金属加热到高温后&#xff0c;缓慢冷却&#xff0c;金属原子会在热能作用下自由运动&#xff0c;逐渐形成能量最低的稳定结构。算法将这一过程抽象为数学模型&#xff1a;“温度 T”&#xff1a;对应物理中的…

架构很简单:业务架构图

缘起业务架构是一个复杂的体系&#xff0c;如何更简单的表达&#xff0c;并能使用起来呢&#xff1f;所谓&#xff1a;大道至简。基于此&#xff0c;这篇文章就开始了。业务是一切架构的开始&#xff0c;如果没有业务&#xff0c;架构又有什么作用呢&#xff1f;所以做架构首先…

【前端埋点】纯前端实现 A/B Test

“纯前端实现 A/B Test”&#xff0c;意思就是 没有后端分流、也不依赖流量网关&#xff0c;那么只能靠前端逻辑来做“流量切分”。 &#x1f3af; 目标 80% 的用户 → A 页面20% 的用户 → B 页面且要保证 同一个用户每次访问结果一致&#xff08;否则用户刷新页面时 A/B 会跳…

Day22_【机器学习—集成学习(3)—Boosting—Adaboost算法】

Adaptive Boosting(自适应提升)是基于 Boosting思想实现的一种集成学习算法&#xff0c;核心思想是通过逐步提高那些被前一步分类错误的样本的权重来训练一个强分类器。一、Adaboost算法直线相当于一个弱学习器&#xff0c;正确的数据权重减小&#xff0c;错误的数据权重增加二…

C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法

C#语言入门详解&#xff08;18&#xff09;传值、输出、引用、数组、具名、可选参数、扩展方法一、传值参数1. 值类型2. 引用类型&#xff0c;并且创建对象3. 引用类型&#xff0c;不创建对象二、引用参数1. 值类型2. 引用类型&#xff0c;创建新对象3. 引用类型&#xff0c;不…

模型部署:(二)安卓端部署Yolov5-v6.0目标检测项目全流程记录

模型部署&#xff1a;&#xff08;二&#xff09;安卓端部署Yolov5-v6.0目标检测项目全流程记录1、下载NCNN项目2、下载基于安卓的yolov5项目3、修改相应的配置文件4、将项目打包成apk包5、部署自己训练的yolov5模型6、相关资料下载&#xff1a;1、下载NCNN项目 # 链接地址 ht…

图形基础算法:如何将点与带曲线边的多边形位置关系算法做稳定

简介判断点与多边形位置关系算法是几何算法中最基础的算法之一&#xff0c;包括布尔运算在内的非常非常多的算法都会用到它。它的稳定是算法库稳定的关键。下面我们从一个边都是直线的多边形开始了解射线法的原理。然后看看引入曲线后会带来哪些问题&#xff0c;以及在实际应用…

react的filber架构

好问题 &#x1f44d; 你问的是 React Fiber 架构。这是 React 16 引入的核心机制&#xff0c;用来解决 React 在大规模更新时的性能问题。下面我给你从 背景 → Fiber 是什么 → 原理 → 优点 → 流程 来系统讲。一、为什么需要 Fiber&#xff1f;在 React 15 及以前&#xff…

Lucky STUN穿透结合群晖NAS实现docker下transmission监听端口动态更新

参考文章 LCUKY系列教程 一 「LUCKY STUN穿透」使用 cURL 自动修改 Transmission 的监听端口 二 「LUCKY STUN穿透」使用 Webhook 自动修改 qbittorrent 的监听端口 三 LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则 四「LUCKY STUN穿透」…

如何在Ubuntu畅玩鸣潮等游戏

本教程只包括Steam上的游戏。# 更新软件源 sudo apt update # 安装Steam sudo apt install steam首先&#xff0c;在Ubuntu的snap商店安装Steam&#xff0c;启动&#xff0c;登陆&#xff0c;下载游戏。到这里的操作都比较简单&#xff0c;对于没有反作弊的游戏&#xff0c;往往…

机器学习09——聚类(聚类性能度量、K均值聚类、层次聚类)

上一章&#xff1a;机器学习08——集成学习 下一章&#xff1a;机器学习10——降维与度量学习 机器学习实战项目&#xff1a;【从 0 到 1 落地】机器学习实操项目目录&#xff1a;覆盖入门到进阶&#xff0c;大学生就业 / 竞赛必备 文章目录一、聚类任务&#xff08;无监督学习…

解决 Docker 构建中 Python 依赖冲突的完整指南

问题背景 在基于 registry.cn-shenzhen.aliyuncs.com/all_dev/dev:invoice-base 镜像构建 Docker 容器时,我们遇到了一个常见的 Python 依赖管理问题: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-…

光子计算芯片实战:Lightmatter Passage互连架构性能评测

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 随着人工智能计算需求呈指数级增长&#xff0c;传统电子计算…

基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索

概述 2018年&#xff0c;TensorFlow Lite团队的Pete Warden曾提出&#xff1a;“机器学习的未来在于微型化”。如今&#xff0c;随着人工智能向高性能视觉强大的视觉语言模型&#xff08;Vision-language models, VLMs&#xff09;发展&#xff0c;对高性能计算资源的需求急剧…

华为Ai岗机考20250903完整真题

华为Ai岗机考20250903 华为自26届秋招&#xff08;2025年起&#xff09;对AI岗位机考进行了改革&#xff0c;考试题型调整为20道选择题&#xff08;15道单选(6分)5道不定项选择(12分)&#xff09;2道编程题(150300)。 题目核心围绕人工智能技术&#xff08;如Transformer架构…

k8s+jenkins+harbor构建Devops平台

一、环境准备1、准备一主一从k8s机器&#xff0c;&#xff08;设备好可以一主多从也行&#xff09;2、一台harbor仓库机器&#xff08;dockerhub访问不了&#xff09;二、安装nfs服务1、在k8s机器上yum install nfs-utils -y systemctl start nfs systemctl enable nfs2、创建共…

为什么 socket.io 客户端在浏览器能连上,但在 Node.js 中报错 transport close?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

人才教育导向下:老年生活照护实训室助力提升学生老年照护服务能力

一、老年生活照护实训室建设背景与意义 &#xff08;一&#xff09;适应老龄化社会需求 我国老龄化程度持续加深&#xff0c;老年照护服务人才缺口不断扩大。培养专业照护人才成为当务之急&#xff0c;职业教育需承担重要责任。点击获取实训室建设方案 &#xff08;二&…