《深入理解C++11:C++11新特性解析与应用》笔记八

第八章 融入实际应用

8.1 对齐支持

8.1.1 数据对齐

c++可以通过sizeof查询数据的长度,但是没有对对齐方式有关的查询或者设定进行标准化。c++11标准定义的alignof函数可以查看数据的对齐方式。

现在的计算机通常会支持许多向量指令,4组8字节的浮点数据,很有潜力改造为能直接操作的向量数据,而默认的对齐方式是8字节的,我们最好能将其对齐在32字节的地址边界上。需要利用c++11新提供的修饰符alignas来重新设定对齐方式。

8.1.2 c++11的alignof和alignas

c++11在新标准中为了支持对齐,主要引入了两个关键字:操作符alignof、对齐描述符alignas。

alignof的操作数表示一个定义完整的自定义类型或者内置类型或者变量,返回值是一个std::size_t类型的整型常量。

alignas既可以接受常量表达式,也可以接受类型作为参数。常量表达式的结果必须是以2的自然数幂次作为对齐值。值越大,表示对齐要求越高。

c++11标准中规定了一个基本对齐值,一般情况下等于平台上支持的最大标量类型数据的对齐值(通常为long double)。我们可以通过alignof(std::max_align_t)来查询其值。设定超过标准对齐的做法叫做扩展对齐。

对齐描述符可以作用于各种数据,可以修饰变量、类的数据成员等,而位域以及用register声明的变量则不可以。

c++11stl库还内建了std::align函数来动态地根据指定的对齐方式调整数据块的位置。

该函数在ptr指向的大小为space的内存中进行对齐方式的调整,将ptr开始的size大小的数据调整为按alignment对齐。

c++11还在标准库中提供了aligned_storage及aligned_union供程序员使用。

8.2 通用属性

8.2.1 语言扩展到通用属性

编译器厂商或组织为了满足编译器客户的需求,设计出了一系列的语言扩展来扩展语法,最常见的就是属性(attribute)。属性是对语言中的实体对象(比如函数、变量、类型等)附加一些的额外注解信息,其用来实现一些语言及非语言层面的功能,或是实现优化代码等的一种手段。

不同的编译器有不同的属性语法,比如对于g++,属性是通过GNU的关键字__attribute__来声明的:__attribute__((attribute-list))。而Windows平台上,则使用关键字__declspec:__declspec(extended-decl-modifier)。c++11的通用属性采用了不一样的设计。

8.2.2 c++11的通用属性

c++11语言中的通用属性使用了左右双中括号的形式:[[attribute-list]]。这样设计的好处是既不会消除语言添加或者重载关键字的能力,又不会占用用户空间的关键字的名字空间。

语法上,c++11的通用属性可以作用于类型、变量、名称、代码块等。对于作用于声明的通用属性,既可以写在声明的开始处,也可以写在声明的标识符之后。而对于作用于整个语句的通用属性,则应该写在语句起始处。而出现在以上两种规则描述的位置之外的通用属性,作用于哪个实体跟编译器具体的实现有关。

现有c++11标准中,只预定义了两个通用属性,分别是[[noreturn]]和[[carries_dependency]]。

8.2.3 预定义的通用属性

[[noreturn]]是用于标识不会返回的函数的。不会返回的函数在被调用完成后,后续代码不会再被执行。主要用于标识哪些不会将控制流返回给原调用函数的函数。典型的例子是:有终止应用程序语句的函数、有无限循环语句的函数、有异常排除的函数等。通过该属性能帮助编译器产生更好的告警信息,同时编译器也可以做更多的诸如死代码消除、免除为函数调用者保存一些特定寄存器等代码优化工作。

[[carries_dependency]]则跟并行情况下的编译器优化有关。事实上,[[carries_dependency]]主要是为了解决弱内存模型平台上使用memory_order_consume内存顺序枚举问题。该通用属性既可以标识函数参数,又可以标识函数的返回值。当标识函数的参数时,它表示数据依赖随着参数传递进入函数,即不需要产生内存栅栏。而当标识函数的返回值时,它表示数据依赖随着返回值传递出函数,同样也不需要产生内存栅栏。

8.3 Unicode支持

8.3.1 字符集、编码和Unicode

通常,我们称ISO/Unicode所定义的字符集为Unicode。在Unicode中,每个字符占据一个码位(code point)。Unicode字符集共定义了1114112个这样的码位,使用从0到10FFFF的十六进制数唯一地表示所有的字符。由于计算机存储数据通常是以字节为单位,而且出于兼容之前的ASCII、大数小段数段、节省存储空间等诸多原因,通常需要一种具体的编码方式来对字符码位进行存储。比较常见的基于Unicode字符集的编码方式有UTF-8、UTF-16及UTF-32。

以UTF-8为例,其采用了1-6字节的变长编码方式编码Unicode,英文通常使用1字节表示,且与ASCII是兼容的,而中文常用3字节进行表示。UFT-8编码由于较为节约存储空间,因而使用得比较广泛。

在中文地区我们还有一些常见的字符集及其编码方式,GB2312、Big5是其中影响最大、使用最广泛的两种。

8.3.2 c++11中的Unicode支持

c++98标准中,为了支持Unicode,定义了宽字符的内置类型wchar_t。在Windows上,多数wchar_t被实现为16位宽,而Linux上则被实现为32位。C++98标准定义中,wchar_t的宽度是由编译器实现所决定的,理论上可以是8位、16位或者32位。带来的问题是包含wchar_t的代码通常不可移植。

c++11引入两种新的内置数据类型来存储不同编码长度的Unicode数据:

char16_t:用来存储UTF-16编码的Unicode数据。

char32_t:用来存储UTF-32编码的Unicode数据。

至于UTF-8编码的Unicode数据,c++11还是使用8字节宽度的char类型的数组来保存。

此外,c++11还定义了一些常量字符串的前缀,这些前缀可以让编译器使字符串按照前缀类型缠身数据:

u8表示为UTF-8编码,u表示为UTF-16编码,U表示为UTF-32编码。(wchar_t的前缀是L)。

按照c/c++的规则,连续在代码中声明多个字符串字面量,则编译器会自动将其连接起来。一旦连续声明多个字符串字面量中的某一个是前缀的,则不带前缀的字符串字面量会被认为与带前缀的字符串字面量是同类型的。

对于Unicode编码字符串的书写,c++11中还规定了一些简明的方式,即在字符串中用‘\u’加4个十六进制数编码的Unicode码位(UTF-16)来标识一个Unicode字符。

相比于定长编码的UTF-16,变长编码的UTF-8的优势在于支持更多的Unicode码位,而且也没有大数大小端问题。不过不能直接数组式访问是UTF-8的最大缺点。此外c++11为char16_t和char32_t分别配备了u16string和u32string等字符串类型,却没有u8string。

现有的c++编程中,总是倾向于在I/O读写的时候采用UTF-8编码,内存中一直操作的是定长的Unicode编码。

8.3.3 关于Unicode的库支持

c11库中新增了一些编码转换函数来完成各种Unicode编码间的转换。

c++对字符转换的支持则稍微复杂一些,新方法需要源自于c++的locale机制的支持。在c++中,通常情况下,locale描述的是一些必须知道的区域特征,如程序运行的国家/地区的数字符号、日期表示、钱币符号,采用的字符集和编码等。

地区的某个特征叫做facet。c++中常见的facet除去num_get/num_put(数值存取)、money_get/money_put等外,还有一种就是codecvt。codecvt能够完成从当前locale下多字符编码字符串到多种Unicode字符编码转换。

c++标准中,规定一共需要实现4种这样的codecvt facet:

考虑到Unicode在序列化存储的时候很少是UTF-16或者UTF-32的,所以从实际出发,没有在c++11中提供支持该功能的u16ifstream、u32ofstream等。

8.4 原生字符串字面量

原生字符串使用用户书写的字符串所见即所得,不再需要如'\t'、'\n'等控制字符来调整字符串中的格式。

c++11中只需要在字符串前加入前缀字母R,并在引号中使用括号左右标识,就可以声明该字符串字面量为原生字符串了。

对于Unicode的字符串,也可以使用相同的方式声明,前缀分别为u8R,uR,UR。使用原生字符串的话,转义字符就不能使用了。原生字符串字面量也遵从连接规则。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ namespace 学习

源自:【C】-命名空间的概念及使用_命名空间的概念及作用-CSDN博客 摘抄:

ISP 基础知识积累

Amber:现有工作必要的技术补充,认识需要不断深入,这个文档后续还会增加内容进行完善。 镜头成像资料 ——干货满满,看懂了这四篇文章,下面的问题基本都能解答 看完思考 1、ISP 是什么,有什么作用&#xff…

加密算法和身份认证

前瞻概念 在了解加密和解密的过程前,我们先了解一些基础概念 明文:加密前的消息叫 “明文” (plain text)密文: 加密后的文本叫 “密文” (cipher text)密钥: 只有掌握特殊“钥匙”的人,才能对加密的文本进行解密,这里…

前端实战第一期:悬浮动画

悬浮动画 像这样的悬浮动画该怎么做&#xff0c;让我们按照以下步骤完成 步骤&#xff1a; 先把HTML内容做起来&#xff0c;用button属性创建一个按钮&#xff0c;按钮内写上悬浮效果 <button classbtn>悬浮动画</button>在style标签内设置样式,先设置盒子大小&…

显示所有中国城市需要多少个汉字?

显示所有中国城市需要多少个汉字呢&#xff1f; 需要3678个汉字&#xff0c;看看我怎么知道的。 第一步&#xff1a;先找到中国的所有城市的名称 去哪里找到中国的所有城市的名称呢&#xff1f; 进入中国天气网&#xff1a;http://www.weather.com.cn/ 使用 F12 打开浏览器的调…

使用results.csv文件数据绘制mAP对比图

yolov5每次train完成&#xff08;如果没有中途退出&#xff09;都会在run目录下生成expX目录&#xff08;X代表生成结果次数 第一次训练完成生成exp0 第二次生成exp1…以此类推&#xff09;。expX目录下会保存训练生成的weights以及result.txt文件&#xff0c;其中weights是训练…

【MFC】计算机图形学实验:熟悉开发环境及工具(代码)

实验内容&#xff1a; 【MFC】计算机图形学实验1&#xff1a;熟悉开发环境及工具_绘制多义线mfc-CSDN博客 画笔和字体只给出两处代码&#xff1a; //创建刷子&#xff0c;设置填充色为黑色 CBrush NewBrush; NewBrush.CreateSolidBrush(RGB(0, 0, 0)); pDC->SelectObjec…

excel公式名称管理器

1.问题 在日常使用excel的时候&#xff0c;发布一个表格文件&#xff0c;需要限制表格的某列或某行只能从我们提供的选项中选择&#xff0c;自己随便填写视为无效&#xff0c;如下图所示&#xff0c;上午的行程安排只能从"在岗"、"出差"、"病假"…

seo分享:慎重使用蜘蛛池

其实要提高搜索引擎蜘蛛的来访次数&#xff0c;唯一的方法还是要通过网站本身的内容更新。频繁更新有质量的内容&#xff0c;才能够提高蜘蛛的来访次数。如果本身内容更新不多&#xff0c;外部引流的蜘蛛过多&#xff0c;最终发现没什么内容索引&#xff0c;蜘蛛来访的次数也会…

x-cmd pkg | 比 du 更好用的查看磁盘空间工具:dust

目录 简介首次用户技术特点竞品和相关作品进一步探索 简介 Dust 是一个用于分析磁盘空间使用情况的命令行工具&#xff0c;旨在提供直观的磁盘分布信息&#xff0c;它的名字是由 “du” 和 Rust 编程语言组合而来。 Dust 的主要功能是提供实时的磁盘空间概览&#xff0c;并以…

华为HCIE-Datacom课程介绍

厦门微思网络HCIE-Datacom课程介绍 一、认证简介 HCIE-Datacom&#xff08;Huawei Certified ICT Expert-Datacom&#xff09;认证是华为认证体系中的顶级认证&#xff0c;HCIE-Datacom认证定位具备坚实的企业网络跨场景融合解决方案理论知识&#xff0c;能够使用华为数通产品…

数据库存储过程

存储过程(特定功能的 SQL 语句集) 一组为了完成特定功能的 SQL 语句集&#xff0c;存储在数据库中&#xff0c;经过第一次编译后再次调用不需要再次编译&#xff0c;用户通过指定存储过程的名字并给出参数&#xff08;如果该存储过程带有参数&#xff09;来执行它。存储过程是…

计算机视觉入门与调优

大家好啊&#xff0c;我是董董灿。 在 CSDN 上写文章写了有一段时间了&#xff0c;期间不少小伙伴私信我&#xff0c;咨询如何自学入门AI&#xff0c;或者咨询一些AI算法。 90%的问题我都回复了&#xff0c;但有时确实因为太忙&#xff0c;没顾得过来。 在这个过程中&#x…

ArrayList学生管理系统

文章目录 1.ArrayList集合和数组的优势对比&#xff1a;1.1 ArrayList类概述1.2 ArrayList类常用方法1.2.1 构造方法1.2.2 成员方法1.2.3 示例代码 1.3 ArrayList存储字符串并遍历1.3.1 案例需求1.3.2 代码实现 1.4 ArrayList存储学生对象并遍历1.4.1 案例需求1.4.2 代码实现 1…

福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!

千里之行&#xff0c;始于足下&#xff0c;若想提高软件编程能力&#xff0c;最最重要的是实践&#xff0c;所谓纸上得来终觉浅&#xff0c;绝知此事要躬行。根据相关【艾宾浩斯遗忘曲线】研究表明&#xff0c;如果不动手实践&#xff0c;记住的东西会很快忘记。 为了便于大家查…

大数据计算基础真题回忆

转载学长20 21的真题 转载链接 注&#xff1a;每年的课件可能会有更改&#xff0c;内容不一样&#xff0c;所以读者复习的时候以所在年份的课件为准 2020 ​ 2021 笔者2023秋 2023 都是大题&#xff0c;没有选择题。 改进的近似算法中&#xff0c;结合具体的例子说明&am…

算法训练营Day36(贪心-重叠区间)

都算是 重叠区间 问题&#xff0c;大家可以好好感受一下。 都属于那种看起来好复杂&#xff0c;但一看贪心解法&#xff0c;惊呼&#xff1a;这么巧妙&#xff01; 还是属于那种&#xff0c;做过了也就会了&#xff0c;没做过就很难想出来。 不过大家把如下三题做了之后&#…

mac远程ssh免密登录

服务器部署经常会登录到远程服务&#xff0c;为方便操作&#xff0c;提高效率对运维人员来说设置免密登录还是很有必要的。其实也是很简单&#xff0c;安以下操作步骤即可。 1、进入到&#xff5e;/.ssh目录下&#xff0c;确认已经生成有公钥与私钥。如果没有请执行发下命令 …

jdk动态代理与cglib代理区别1

动态代理有jdk动态代理及cglib代理&#xff0c;下面描述jdk动态代理 jdk动态代理 看了 上云 老师的视频&#xff0c;得出此理解 pom文件 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-st…

(Linux)虚拟机配置固定IP

Linux操作系统的IP地址是通过DHCP服务获取的&#xff0c;也就是动态获取IP地址&#xff0c;每次重启设备后都会获取一次&#xff0c;会导致IP地址频繁变更&#xff0c;为了不频繁更新映射关系&#xff0c;我们需要IP地址固定下来。 1.在VM中配置IP地址网关和网段 打开虚拟网络…
最新文章