当前位置: 首页 > news >正文

c++11特性与c++17特性

1、自动类型推导auto

// C++11
auto func1() -> int // 需要指定返回值类型
{return 10;
}auto func2() -> std::function<void()>
{auto lambda = []() { };return lambda;
}// c++17
// 之后无需指定返回值类型
auto func1()
{return 10;
}auto func2()
{auto lambda = []() { };return lambda;
}

lambda

// C++11
class Any {
public:Any() { printf("%s()\n", __func__); }~Any() { printf("%s()\n", __func__); }void print() const { printf("%s()\n", __func__); }auto exec() -> std::function<void()>{auto lambda = [this](){this->print();};return lambda;}};auto get() -> std::function<void()>
{Any any;return any.exec();
}int main(int argc, char **argv)
{get()(); // 调用一个已经析构对象的this指针会出现SIGSEGVreturn 0;
}// C++17
class Any {
public:Any() : this_e(this) { printf("%s() this = %p\n", __func__, this); }Any(const Any &other) { printf("%s(const Any &other)\n", __func__); }~Any() { printf("%s()\n", __func__); }void print() const { printf("%s() this = %p\n", __func__, this); }void print_nonconst() { printf("%s()\n", __func__); }auto exec() -> std::function<void()>{auto lambda = [*this](){// 此时*this是const Any类型, 会调用一次拷贝构造, 当不存在拷贝构造时无法捕获*thisassert(this != this_e); // 由于拷贝构造不会修改this_e的值,故this_e还保留着之前对象的地址this->print(); // 同样可以使用this(但只能调用const属性的函数), 此时的this是*this新创建的Any的地址// 通过const_cast来消除const,从而调用非const属性的函数const_cast<Any *>(this)->print_nonconst();};return lambda;}void *this_e;
};/*** c++11无法捕获*this,导致在get()函数返回的lambda在main函数调用时会崩溃* * c++17后可以捕获*this,以获取对象的拷贝*/
auto get() -> std::function<void()>
{Any any;return any.exec();
}int main(int argc, char **argv)
{get()();return 0;
}

结构化绑定

// C++17
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
#include <map>struct Node
{int size;char buffer[128];
};Node &get()
{static Node node;node.size = 10;strncpy(node.buffer, "Hello World", sizeof(node.buffer));printf("node.buffer = %p\n", node.buffer);return node;
}void func()
{std::map<std::string, int> map;map["Hello"] = 100;map["World"] = 200;// 在c++17之前需要声明iterator, 通过iterator访问for (const auto &[key, val] : map) {std::cout << "key = " << key << ", value = " << val << std::endl;}
}int main(int argc, char **argv)
{// 此处声明时需与对象的元素个数一致,且按照元素顺序声明// 可以是auto(拷贝), auto &(引用), const auto &(常量引用)const auto &[size, buffer] = get();std::cout << "size = " << size << ", buffer = " << buffer << std::endl;printf("main() buffer = %p\n", buffer);func();return 0;
}

聚合体

#include <iostream>
#include <string>struct Base {Base(const std::string &_s, int _l) : str(_s), len(_l) { }std::string str;int len;
};struct Other : public Base {bool valid;
};int main(int argc, char **argv)
{{// 构造函数Base b("hello", 5);}{// 聚合体初始化Base b = {"hello", 5};Base b_{"hello", 5}; // C++11之后可以省略等号// 一般情况下不建议使用如下方式初始化,当成员增多时这种写就会生涩难懂且繁琐Other o{{"hello", 5}, true}; // C++17之后支持初始化基类(gcc和msvc1920不支持省略基类的大括号)// 但聚合体初始化常可以用来初始化一些带有默认值的静态对象// QT的源代码中存在许多聚合体初始化// 比如 QHashData::shared_null}return 0;
}
/*** 聚合体初始化需要满足* 1、子类和父类成员需得是public* 2、子类父类都没有虚函数*/

新增属性

[[fallthrough]]
[[nodiscard]]
[[maybe_unused]]

if constexpr

编译期如果满足条件,则只对if的内容进行编译,省去else的编译,反之只编译else内容

template <bool flag>
const char *getDefaultPath()
{const char * path;if constexpr(flag) {path = "/default/ptah";} else {path = "/other";}return path;
}int main(int argc, char **argv)
{getDefaultPath<true>();return 0;
}// g++ -S test.cc -o test.s -std=c++17
	.file	"test.cc".text.globl	main.type	main, @function
main:
.LFB1:.cfi_startprocpushq	%rbpmovq	%rsp, %rbpsubq	$16, %rspmovl	%edi, -4(%rbp)movq	%rsi, -16(%rbp)call	_Z14getDefaultPathILb1EEPKcvmovl	$0, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE1:.size	main, .-main.section	.rodata
.LC0:.string	"/default/ptah".section	.text._Z14getDefaultPathILb1EEPKcv,"axG",@progbits,_Z14getDefaultPathILb1EEPKcv,comdat.weak	_Z14getDefaultPathILb1EEPKcv.type	_Z14getDefaultPathILb1EEPKcv, @function
_Z14getDefaultPathILb1EEPKcv:
.LFB2:.cfi_startprocpushq	%rbpmovq	%rsp, %rbpleaq	.LC0(%rip), %raxmovq	%rax, -8(%rbp)movq	-8(%rbp), %raxpopq	%rbpret.cfi_endproc
.LFE2:.size	_Z14getDefaultPathILb1EEPKcv, .-_Z14getDefaultPathILb1EEPKcv.ident	"GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0".section	.note.GNU-stack,"",@progbits

组件库

std::optional<>

class Any {
public:Any() { printf("%s()\n", __func__); }Any(const Any &other) = delete; /// { printf("%s(const Any &other)\n", __func__); }~Any() { printf("%s()\n", __func__); }
};int main(int argc, char **argv)
{// std::optional支持等号运算符,使用等号时会产生一次拷贝// std::optional<Any> opt = Any();// 通过std::make_optional构造的不会产生拷贝std::optional<Any> opt = std::make_optional<Any>();if (opt) { // or opt.has_value()std::cout << "opt.value()" << std::endl;}return 0;
}

std::variant<>

作用类似union,但是比union更加方便。std::variant只包含模板参数中的一个类型的值,当转换为其他值时会抛出异常。
std::variant是一个变参模板类,可以存放更多的类类型,而不仅限于基础类型。

#include <stdio.h>
#include <iostream>
#include <variant>
#include <assert.h>class Any {
public:Any() { printf("%s()\n", __func__); }Any(const Any &other) { printf("%s(const Any &other)\n", __func__); }~Any() { printf("%s()\n", __func__); }
};int main(int argc, char **argv)
{std::variant<std::string, Any> var_union("hello");assert(0 == var_union.index());const std::string &val = std::get<0>(var_union); // 编译期代码,index()属于运行期,所以不能用index替换0std::cout << val << std::endl;try {const Any &any = std::get<Any>(var_union);assert(true && "never reach here");} catch (...) {std::cout << "catch exception\n";}var_union = Any();assert(1 == var_union.index());return 0;
}

std::any

std::any可以储存任何值的类型,下面以360开源的代码为例

#include <typeinfo>
#include <utility>
#include <assert.h>
// 其核心是Placeholder, 并且运用到了RTTI技术来做安全的类型转换
namespace eular {
// NOTE: class Any need the copy structure
class Any {
public:Any() : content_(nullptr) {}~Any() {if (content_) {delete content_;}}template<typename ValueType>explicit Any(const ValueType& value): content_(new Holder<ValueType>(value)) {}Any(const Any& rhs): content_(rhs.content_ ? rhs.content_->clone() : nullptr) {}public:Any& swap(Any& rhs) {std::swap(content_, rhs.content_);return *this;}template<typename ValueType>Any& operator=(const ValueType& rhs) {Any(rhs).swap(*this);return *this;}Any& operator=(const Any& rhs) {Any(rhs).swap(*this);return *this;}bool empty() const {return !content_;}const std::type_info& type() const {return content_ ? content_->getType() : typeid(void);}template<typename ValueType>ValueType operator()() const {if (getType() == typeid(ValueType)) {return static_cast<Any::Holder<ValueType>*>(content_)->held_;} else {return ValueType();}}protected:class PlaceHolder {public:virtual ~PlaceHolder() {}public:virtual const std::type_info& getType() const = 0;virtual PlaceHolder* clone() const = 0;};template<typename ValueType>class Holder : public PlaceHolder {public:Holder(const ValueType& value): held_(value) {}virtual const std::type_info& getType() const {return typeid(ValueType);}virtual PlaceHolder* clone() const {return new Holder(held_);}ValueType held_;};protected:PlaceHolder* content_;template<typename ValueType>friend ValueType* any_cast(Any*);
};template<typename ValueType>
ValueType* any_cast(Any* any) {if (any && any->getType() == typeid(ValueType)) {return &(static_cast<Any::Holder<ValueType>*>(any->content_)->held_);}return nullptr;
}template<typename ValueType>
const ValueType *any_cast(const Any* any) {return any_cast<ValueType>(const_cast<Any *>(any));
}template<typename ValueType>
ValueType any_cast(const Any& any) {const ValueType *result = any_cast<ValueType>(&any);assert(result);if (!result) {return ValueType();}return *result;
}

std::shared_mutex

读写锁

std::string_view

std::string_view对指向的内容是只读的,其操作是对指针的偏移,所以性能比std::string高

std::filesystem

具体可查看cppreference的filesystem

相关文章:

c++11特性与c++17特性

1、自动类型推导auto // C11 auto func1() -> int // 需要指定返回值类型 {return 10; }auto func2() -> std::function<void()> {auto lambda []() { };return lambda; }// c17 // 之后无需指定返回值类型 auto func1() {return 10; }auto func2() {auto lambda…...

Redis02: Redis基础命令

一、基础命令 先启动redis服务&#xff0c;使用redis-cli客户端连到redis数据库里面 1. 获取符合规则的键: keys 要点&#xff1a; &#xff08;1&#xff09;keys 后面可以指定正则表达式 &#xff08;2&#xff09;在生产环境下建议禁用keys命令&#xff0c;因为这个命令会查…...

MDK的HardFault硬件异常和NMI异常原因总结

发出来&#xff0c;出现问题自行比对&#xff0c;现在一些代码&#xff0c;也会对这个进行分析。硬件异常原因&#xff1a; Unaligned load or store Load 或者 store 指令访问未对齐地址 Undefined Instruction 执行 ARM 未定义的指令 EPSR Fault 当前程序没有在 Thumb 状态下…...

视频图像质量诊断

视频图像质量诊断有哪些原理&#xff0c;视频图像质量诊断有哪些算法&#xff1f; 视频图像质量诊断技术支持对视频黑屏、视频干扰、视频卡顿、视频遮挡、亮度异常、图像偏色、视频模糊、视频冻结、视频抖动、场景变更、无字符叠加等20种视频图像质量异常进行诊断&#xff0c;…...

make、Makefile项目自动化构建工具

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;前言自动化构建工具是干什么的呢&#xff1f;主要是为了让我们对指令进行一些设置&#xff0c;就比如说&#xff0c;假如一个项目里有很多个源文件&…...

Linux系统之Uboot、Kernel、Busybox思考之一

目录 一 基础环境 1 硬件基础环境 2 软件基础环境 2.1 Uboot 2.2 内核 2.3 文件系统 二 启动过程 1 2 3 4 5 6 7 一 基础环境 1 硬件基础环境 CPU、内存和FLASH为基础环境&#xff0c;有了这三样&#xff0c;程序就可以跑起来。在此基础上补充各种外设&#xff…...

CCNP350-401学习笔记(401-450题)

401、What is the function of vBond in a Cisco SDWAN deployment? A. initiating connections with SD-WAN routers automatically B. pushing of configuration toward SD-WAN routersC. onboarding of SDWAN routers into the SD-WAN overlay D. gathering telemetry dat…...

一文带你看透前端世界里的日期时间,对就是Date

很高兴我们能够通过不同空间&#xff0c;不同时间&#xff0c;通过这篇博客相识&#xff0c;那一定是一种缘分&#xff0c;一种你和狗哥的缘分。今天我希望通过这篇博客对我所熟知的前端世界里的日期时间做一个汇总&#xff0c;不止是代码上的汇总哦&#xff01; 目录 一、时区…...

易基因|RRBS单碱基绘制580种动物的基因组规模DNA甲基化谱:Nature子刊

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。2023年01月16日&#xff0c;奥地利科学院分子医学研究中心(CeMM)研究团队在《Nat Commun》杂志发表了题为“Comparative analysis of genome-scale, base-resolution DNA methylation prof…...

面试官:能用JavaScript手写一个bind函数吗

经常会看到网上各种手写bind的教程&#xff0c;下面是我在自己实现手写bind的过程中遇到的问题与思考。如果对于如何实现一个手写bind还有疑惑的话&#xff0c;那么可以先看看上面两篇文章。 手写bind vs 原生bind 我们先使用一个典型的手写bind的例子&#xff0c;代码如下&a…...

美国拟发布纽扣电池或硬币电池安全标准和通知要求ANSI C18. 3M

2023年2月10日&#xff0c;美国向WTO提交G/TBT/N/USA/1964号通报&#xff0c;拟发布纽扣电池或硬币电池以及含有此类电池的消费品的安全标准和通知要求&#xff0c;征求意见截止日期为2023年3月13日&#xff0c;拟通过日期和生效日期待定。联[1]系 拟定规则通知根据H.R.5313瑞…...

双因素方差分析

一、案例与数据 一家大型商业银行在多地区设有分行&#xff0c;其业务主要是进行基础设施建设&#xff0c;国家重点项目建设&#xff0c;固定资产投资等项目的贷款。近年来&#xff0c;该银行的贷款额平稳增长&#xff0c;但不良贷款额也有较大比例的提高&#xff0c;这给银行…...

[ vulhub漏洞复现篇 ] Drupal XSS漏洞 (CVE-2019-6341)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

「TCG 规范解读」第8章 TPM工作组 TPM 1.2中 SHA1的使用

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…...

熵权法计算权重

文章目录1. 多属性决策问题2. 熵&#xff08;entropy&#xff09;3. 信息熵4. 熵权法5. 熵权法的实现基于信息论的熵值法是根据各指标所含信息有序程度的差异性来确定指标权重的客观赋权方法&#xff0c;仅依赖于数据本身的离散程度。熵用于度量不确定性&#xff0c;指标的离散…...

redis实现用户签到,统计活跃用户,用户在线状态,用户留存率

开发的过程中&#xff0c;可能会遇到用户签到、统计当天的活跃用户、以及每个用户的在线状态&#xff0c;用户留存率的开发需求&#xff0c;可能会用传统的方法&#xff0c;根据相应的需求设计数据库表等&#xff0c;但这样耗费的存储空间大&#xff0c;以及性能方面也不会太好…...

MySQL中有多少种索引?索引的底层实现原理

索引存储在内存中&#xff0c;为服务器存储引擎为了快速找到记录的一种数据结构。索引的主要作用是加快数据查找速度&#xff0c;提高数据库的性能。索引的分类(1) 普通索引&#xff1a;最基本的索引&#xff0c;它没有任何限制。(2) 唯一索引&#xff1a;与普通索引类似&#…...

LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解

LeetCode经典算法题&#xff1a;二叉树遍历&#xff08;递归遍历迭代遍历层序遍历&#xff09;以及线索二叉树java详解 文章目录二叉树遍历题目描述解题思路与代码递归遍历迭代遍历层序遍历线索二叉树&#xff1a;二叉树遍历 题目描述 从根节点往下查找&#xff0c;先找左子树…...

【Java闭关修炼】MyBatis-接口代理的方式实现Dao层

【Java闭关修炼】MyBatis-接口代理的方式实现Dao层实现规则代码实现代理对象分析接口代理方式小结实现规则 映射配置文件中的名称空间必须和Dao层接口的全类名相同映射配置文件的增删改查标签的id属性必须和Dao层接口方法的参数相同映射配置文件中的增删改查标签的parameterTyp…...

2022年网络安全政策态势分析与2023年立法趋势

近日&#xff0c;公安部第三研究所网络安全法律研究中心与 360 集团法务中心联合共同发布了《全球网络安全政策法律发展年度报告&#xff08;2022&#xff09;》。《报告》概览2022年全球网络安全形势与政策法律态势&#xff0c;并对2023年及后续短期内网络安全政策、立法趋势进…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...