C++17

news2024/11/15 12:37:22

目录

  • 基本语言特性
    • 结构化绑定
    • if和switch初始化器
  • std::string_view
  • 属性
    • [[nodiscard]]
    • [[maybe_unused]]
    • [[fallthrough]]
  • 模板特性
  • 新的标准库组件
    • std::optional<>
    • std::variant<>
    • std::any
    • std::byte
    • std::as_const
  • 文件系统库
  • 零星新特性

基本语言特性

结构化绑定

概念:允许用一个对象的元素或成员同时实例化多个实体,形如:

绑定到map这个对象

map<int, string> m;
m.insert({1, "hello"});
m.insert({2, "world"});
m.insert({3, "good"});
for(const auto& [key, val]: m) {
  std::cout << key << ": " << val << "\n";
}

绑定到struct对象

struct MyStruct {
  int i = 0;
  std::string s;
};
MyStruct ms;
auto [u, v] = ms;

为了理解结构化绑定,必须意识到这里面其实有一个隐藏的匿名对象,结构化绑定时新引入的局部变量名其实都指向这个匿名对象的成员

auto [u, v] = ms;
auto e = ms;
aliasname u = e.i;
aliasname v = e.s;

使用修饰符
结构化绑定适用的场景

  • 对于所有非静态成员都是public的结构体和类,可以把每个成员绑定到一个新的变量名上
  • 对于原生数组,可以把数组的每个元素绑定到新的变量名上
  • 对于任何类型,可以使用tuple-like API来绑定新的名称,std::tuple, std::pair, std::array

注意:

  • 必须为结构化绑定使用auto关键字,例如,不能用int代替auto
  • 使用结构化绑定声明的变量数量必须与右侧表达式中的值数量匹配
  • 通常使用auto& 或者const auto&代替auto

if和switch初始化器

C++允许在if语句中包括一个初始化器,语法如下:

if(<initializer>; <conditional_expression>) { ... }
switch(<initializer>; <expression>) { ... }

if语句的条件表达式<initializer>里定义的变量将在整个if语句中有效,此类变量在if语句之外不可用

// 带初始化的if和switch语句
int b = 20;
if(int a = 10; b != a) {
    cout << a << endl;
    return;
}

可以在加锁的地方使用
内联变量
可以在头文件中以inline的方式定义全局变量
内联变量产生的动机:C++不允许在类里初始化非常量静态成员,可以在类定义的外部定义并初始化非常量静态成员,但如果被多个cpp文件同时包含的话又会引发新的错误,根据一次性定义原则,一个变量或实体的定义只能出现在一个编译单元内,除非该变量或实体被定义为inline
对于静态成员,在C++17中constexpr修饰符现在隐含着inline

static constexpr int n = 5;  // 等价于  
inline static constexpr int n = 5;
// 聚合体
struct Data {
    std::string name;
    double value;
};
// 聚合体初始化
Data x = {"test1", 6.778};
// 在C++11中起可以忽略等号
Data x {"test1", 6.778};
// 自C++17起聚合体可以拥有基类
struct MoreData : Data {
    bool done;
};
// 初始化时可以用如下两种方式:
MoreData y {{"test1", 6.778}, false };
MoreData y { "test1", 6.778, false };

std::string_view

头文件包含:#include<string_view>
应用场景:针对接收只读字符串的函数形参而言,如果是const char*的话,如果使用std::string,则必须调用其上的c_str()和data()来获取,但这样将失去std::string良好的面向对象的方面及其方法;如果改用std::string& 始终需要传入std::string。例如,传递一个字符串变量,编译器将默认创建一个临时字符串对象并将该对象传递给函数。所以有时需要重载多个版本,但这并不是一个很好的解决方案。
C++17中引入string_view解决了这类问题。
string_view基本就是const string&的简单替代品,但并不会复制字符串,不会产生开销。

属性

[[nodiscard]]

鼓励编译器在某个函数的返回值未被使用时给出警告,但并不意味着编译器必须这么做

[[nodiscard]] int func() { return 42; }
int main() { func(); } 

以上代码编译器会发出告警
从C++20开始,可以以字符串的形式为[[nodiscard]]提供一个原因,例如:

[[nodiscard("Some explanation")]] int func();

在这里插入图片描述

[[maybe_unused]]

int func(int param1, int param2) { return 20; }

如果编译器告警级别设置的足够高,会报变量没有使用的警告。通过[[maybe_unused]]可以避免编译器在某个变量未被使用时发出警告。

void foo(int val, [[maybe_unused]] std::string str) {
    ...
}

class MyClass {
   char c;
   int i;
   [[maybe_unused]] char xxx[32];
};

[[maybe_unused]]属性可用于类和结构体,非静态数据成员,联合,typedef,类型别名,变量,函数,枚举以及枚举值。
注意:不能在一条语句上应用[[maybe_unused]]。
这个写法可以代替C或者以前通过 (void)var; 这种方式避免未使用的变量报告警的方法。

[[fallthrough]]

可以避免编译器在switch语句中某一个标签缺少break语句时发出警告

模板特性

constexpr if: 编译器if语句

新的标准库组件

std::optional<>

头文件:#include<optional>, 模拟了一个可以为空的任意类型的实例,可以被用作成员,参数,返回值等。如果想要允许值是可选的,则可以将optional用作函数的参数;如果函数可能返回也可能不返回某些内容,可以将optional用作函数的返回类型。这消除了从函数中返回”特殊“值的需要,如nullptr,end(), -1, EOF等。
同时定义了以下:

  • std::nullopt ,
  • 异常类std::bad_optional_access:派生自std::exception ,当无值的时候访问值将会出现异常。
  • std::in_place:可选对象也使用了<utility>头文件中定义的 std::in_place 对象来初始化多个参数的可选对象

操作:

  • 构造/析构/=
  • make_optional<>():创建一个用参数初始化的可选对象
  • has_value():判断一个optional是否有值,或者也可以简单的将optional用在if语句中。
  • value() :如果optional有值,可以用value或者解引用运算符访问
optional<int> getData(bool qiveIt) {
  if(qiveIt) { return 32; }
  return nullopt;
}
int main() {
    optional<int> data1 { getData(true) };
    optional<int> data2 { getData(false) };
    if(data1.has_value()) { std::cout << "data1: " << data1.value() << std::endl; }
    if(data2.has_value()) { std::cout << "data2: " << data2.value() << std::endl; }
}

std::variant<>

头文件:#include <variant>
说明:提供了一个新的联合类型,最大的优势是提供了一种新的具有多态性的处理异质集合的方法,也就是说可以处理不同类型的数据,并且不需要公共基类和指针
如果第一个类型没有默认构造函数,那么调用variant的默认构造函数将会导致编译期错误,为支持第一个参数没有默认构造的情况,C++标准库提供了std::monostate,可以作为第一个选项来保证variant能默认构造
可以从variant派生

std::any

头文件:#include<any>
说明:是一种在保证类型安全的基础上还能改变自身类型的值类型。也就是说,它可以持有任意类型的值,并且它知道当前持有的值是什么类型
std::any对象同时包含了值和值的类型。
为了将当前值转换为真实的类型,必须要使用any_cast<>,如果转换失败,可能是因为对象为空或者与内部值的类型不匹配,会抛出一个std::bad_any_cast 异常。
拷贝std::any的开销一般都很大,推荐以引用传递对象,或者move值,std::any支持部分move语义

std::byte

头文件:#include <cstddef>
在C++17之前使用char或者unsigned char来表示一个字节,但这些类型使得像是在处理字符。C++17提供了std::byte。这个类型代表内存的最小单位,std::byte本质上代表一个字节的值,但不能进行数字或字符的操作,也不对每一位进行解释
注意:std::byte实现和unsigned char类似,不能保证8位;底层实现的类型是unsigned char,所以大小总为1
列表初始化是唯一可以直接初始化std::byte对象的方法
没有定义输入和输出运算符,因此不得不把它转换为整数类型再进行IO

std::as_const

include<utility>,该方法接收一个引用参数,返回他的const引用版本。等价于 const_cast<const T&>(obj)

文件系统库

#include, 命名空间:std::filesystem,一个很常见的操作时定义:namespace fs = std::filesystem
异常:std::filesystem::filesystem_error

零星新特性

  1. 支持嵌套命名空间,如
namespace A {
  namespace B {
    namespace C {
	}
  }
}

可以写成:

namespace A::B::C {}
  1. std::size() 计算基于C风格数组的大小
int myArray[3] { 2 };
std::size(myArray);

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

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

相关文章

ubuntu安装WPS2019以及解决缺少字体问题

环境&#xff1a;ubuntu22.04.2 LTS 步骤&#xff1a; 1.去官网下载最新的WPS&#xff0c;官网地址如下&#xff1a;WPS Office 2019 for Linux-支持多版本下载_WPS官方网站 2.sudo dpkg -i 安装包.deb 3.安装完成&#xff0c;首次用WPS打开某个文档&#xff0c;会出现如下报…

硬件入门之什么是三极管

硬件入门之什么是三极管 文章目录 硬件入门之什么是三极管一、三极管是什么&#xff1f;&#xff08;百度百科&#xff09;三极管的3种工作状态分别是截止状态、放大状态、饱和状态 二、实际应用场景1.放大电路 &#xff08;放大状态&#xff09;2、开关电路&#xff08;截至状…

【聚类算法】谱聚类spectral clustering

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 说明&#xff1a; 后续增补 1. 正文 1.1 整体理解 谱聚类&#xff08;Spectral Clustering&#xff09;是一种基于图论的聚类方法&#xff0c;将带权无…

基于java,springboot的校园闲置物品租售系统设计与实现

背景 校园闲置物品租售系统应有的主要功能模块&#xff0c;本系统有管理员、卖家和用户&#xff0c;管理员&#xff1b;首页、个人中心、用户管理、卖家管理、商品种类管理、商品信息管理、商品租借管理、商品购买管理、闲置鱼塘、系统管理&#xff0c;用户&#xff1b;首页、…

Java并发中的原子性、可见性和有序性

基于JMM的内存模型&#xff0c;Java并发编程的核心问题&#xff1a;原子性、可见性、有序性 那么在此之前&#xff0c;我们有必要先说一下Java的JMM内存模型&#xff1a;java内存模型&#xff0c;是java虚拟机规范的一种工作模式&#xff0c;它将内存分为主内存和工作内存。线…

【机器学习】十大算法之一 “PCA”

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

高性能计算的意义是什么

高性能计算&#xff08;High-Performance Computing&#xff0c;HPC&#xff09;在现代科学、工程和商业领域中具有重要意义。以下是一些高性能计算的重要意义&#xff1a; 加速科学研究和创新&#xff1a;高性能计算可以提供大规模的计算能力和存储资源&#xff0c;使得科学家…

stm32数据对齐、PRESERVE8、freertos堆栈

为什么需要数据对齐&#xff1f; 避免数据在内存中跨边界存储&#xff0c;减少读取数据次数&#xff0c;提高效率&#xff0c;本质上是以空间换时间的做法 下图中属于同一水平位置的为同一边界 变量在同一边界里的一次存储周期就可以读取 一旦跨了上下两个边界来存储就需要至少…

干爆源码系列之Step by step lldb/gdb调试多线程

Step by step lldb/gdb调试多线程 0.叙谈1.断点分析2.多线程切换 2.1 并发队列 2.1.1 两次入队 2.2 线程调度 2.2.1 执行build端子MetaPipeline 2.2.1.1 Thread6调度第一个PipelineInitializeTask 2.2.1.2 Thread7调度第二个Pipelin…

TypeScript 数据联合类型的解读

概念&#xff1a; 联合类型&#xff08;Union Types&#xff09;表示取值可以为多种类型中的一种&#xff0c;或者也可以理解将多个类型合并为一个类型对变量进行注解。 语法结构&#xff1a; 联合类型使用 | 分隔每个类型。 let 变量&#xff1a;类型1 | 类型2 | 类型3… 案列…

基于Java校园代购服务订单系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

你的前端技术是否能通过这些高频面试题?

文章目录 1.储存了某个数据到 localStorage&#xff0c;立即进行 localStorage.getItem&#xff0c;能否取到值&#xff1f;2.实现异步的方式有几种3.异步不阻塞4.选择 div 的第二个子元素5.display: none 和 visibility: hidden 的区别6.如果想要让一个元素的宽高包含元素的 b…

【初识C语言】选择语句+循环语句+函数+数组

文章目录 前言1. 选择语句2. 循环语句3. 函数4. 数组 前言 C语言是一门结构化的程序设计语言 顺序结构&#xff1b; 选择结构&#xff1b; 循环结构。 1. 选择语句 生活中处处面临着选择&#xff0c;如果你好好学习&#xff0c;校招时拿一个好offer&#xff0c;走上人生巅峰。…

关于程序员的工作总结

程序员工作总结篇1 从我x月x日进入公司到现在已经过去一年了&#xff0c;从一名刚刚结束实习的学生到一名独立的开发人员&#xff0c;角色改变了&#xff0c;职责也改变了。虽然已经预计了工作之中会有很多困难&#xff0c;可是在实际的项目开发中&#xff0c;自己所遇到远远不…

(超级详细)如何在Mac OS上的VScode中配置OpenGL环境并编译

文章目录 安装环境下载GLAD与GLFW一、下载GLAD二、下载GLFW 项目结构配置测试程序与项目的编译测试可执行文件HelloGL 安装环境 机器&#xff1a;macbook air 芯片&#xff1a; M1芯片&#xff08;arm64&#xff09; macOS&#xff1a;macOS Ventura 13.4 VScode version&#…

Pytorch数据类型Tensor张量操作(操作比较全)

文章目录 Pytorch数据类型Tensor张量操作一.创建张量的方式1.创建无初始化张量2.创建随机张量3.创建初值为指定数值的张量4.从数据创建张量5.生成等差数列张量 二.改变张量形状三.索引四.维度变换1.维度增加unsqueeze2.维度扩展expand3.维度减少squeeze4.维度扩展repeat 五.维度…

SpringCloud Alibaba入门5之使用OpenFegin调用服务

我们继续在上一章的基础上进行开发 SpringCloud Alibaba入门4之nacos注册中心管理_qinxun2008081的博客-CSDN博客 Feign是一种声明式、模板化的HTTP客户端。使用Feign&#xff0c;可以做到声明式调用。Feign是在RestTemplate和Ribbon的基础上进一步封装&#xff0c;使用RestT…

SAP从入门到放弃系列之BOM行项目-虚拟装配-Part4

文章目录 虚拟组件&#xff08;Phantom assemblies&#xff09;&#xff1a;作用&#xff1a;BOM中虚拟件维护的方式&#xff1a; 物料主数据维度BOM组件维度&#xff08;数据优先级最高&#xff09; BOM组件的展开类型&#xff1a;BOM组件的特殊采购类数据测试示例&#xff1…

基于open62541库的OPC UA协议节点信息查询及多节点数值读写案例实践

目录 一、OPC UA协议简介 二、open62541库简介 三、 opcua协议的多点查询、多点读写案例服务端opcua_server 3.1 opcua_server工程目录 3.2 程序源码 3.3 工程组织文件 3.4 编译及启动 四、opcua协议的多点查询、多点读写案例客户端opcua_client 4.1 opcua_client工程目录 4…

医院管理系统源码PACS超声科室源码DICOM影像工作站

一、医学影像系统&#xff08;PACS&#xff09;是一种应用于医院影像科室的系统&#xff0c;主要任务是将日常产生的各种医学影像&#xff08;如核磁、CT、超声、X光机、红外仪、显微仪等设备产生的图像&#xff09;通过各种接口&#xff08;模拟、DICOM、网络&#xff09;以数…