引言

上周 C++ 标准委员会在科隆举行了7月会议(WG21)。 会议报告请戳:《Trip Report: C++ Standards Meeting in Cologne, July 2019》

会议中重点针对 C++20 标准已经投票通过的特性进行了若干修正,并对一些草案进行了讨论和投票。相比上次会议,通过了一些新的草案。

移除的语言特性

  • 合约(Contracts)

新增的主要语言特性

  • 类模板参数推导优化
  • constexpr 容器的语言支持
  • constinit 关键字
  • using enum
  • 在大多数场景下废弃 volatile 关键字

新增的主要标准库特性

  • 文本格式化支持
  • C++20 Synchronization Library
  • Input Range 适配器
  • constexpr std::vector
  • constexpr std::string
  • 线程可中断 join 支持(Stop Token)
  • std::source_location
  • 概念(Concepts)采用 C++ 标准库命名规范
  • constexpr std::invoke

新增特性介绍

上述特性是本人认为的本次会议投票通过的主要特性。若要浏览全部特性列表,请戳引言中的连接。

下面我将其中一些关键特性作简要介绍。

constinit 关键字

这是新引入的一个关键字,用于强制标记一个全局变量的初始化在编译期完成。若初始化表达式无法在编译期求值,则会引发编译错误。这样便可以避免全局变量的隐式运行时初始化带来的各种各样难以调试的 BUG。

示例:

const char* g() { return "运行时初始化"; }
constexpr const char* f(bool p) { return p ? "常量初始化" : g(); }constinit auto c = f(true); // OK
constinit auto d = f(false); // 编译错误

using enum

这个特性算是对现有 using 语句用法的一个功能补全。它允许 using 语句运用在 enumenum class 之中。

给出枚举:

// china_railway.hpp
enum class china_railway
{cr400af,cr400bf,cr200j
};

用法1:

using enum china_railway;
constexpr auto train_type = cr400af;

用法2:

struct foo
{// 引入枚举成员。using enum china_railway;
};void geek()
{foo f;auto a = f.cr400af; // 使用类实例,合法auto b = foo::cr200j; // 使用类名,合法
}

用法3:

using china_fuxing_trains = china_railway;
using rubbish = china_railway::cr200j; // 枚举值别名
constexpr auto type = china_fuxing_trains::cr400bf;
constexpr auto fake_emu_train = rubbish; // 和 cr200j 等价

文本格式化支持

这是继模块、协程和概念后又一个重磅特性。它弥补了 C++ 标准库缺乏文本格式化支持的一个遗憾。这次通过的提案基于开源库 fmt,语法十分优雅。文本格式化主要通过两个新的标准库函数 std::formatstd::format_to 来实现。

示例1:std::format 基本用法

// 自动编号
auto text1 = std::format("{} 是动车组,但 {} 却不是。", "CR400AF", "CR200J");// 手动编号
auto text2 = std::format("我国领土面积 {0} 万平方公里,人口有 {1} 亿。", 960, 14);// 取消“{}”的转义。
// text3 = "我们的分组是:{100, 200, 300}。"
auto text3 = std::format("我们的分组是:{{{0}, {1}, {2}}}。", 100, 200, 300);

示例2:std::format 格式化控制

std::format 函数支持高级格式化控制。它使用格式控制表达式进行格式化输出。标准格式控制表达式的形式如下所示。

"{[arg_index]:[[fill]align][sign]['#']['0'][width]['.' precision][type]}"

看似很复杂的亚子,其实不难,让我们通过如下的表格来解析。

说明:上式中的方括号[]代表为可选参数。

参数 取值 说明
arg_id 参数编号 如 0,1,2,...
fill 除了 '{' 和 '}' 外的任意字符 用于格式填充的字符
align '<', '>', '=', '^' 控制对齐方式
sign '+', '-', '空格' 控制正负号显示方式
'#' 控制数值类型输出是否添加前缀
width 非零整数 或 '{' arg_id '}' 控制文本长度,若不足将使用 fill 填充
precision 整数 或 '{' arg_id '}' 控制小数点后的保留的位数
type 'a', 'A', 'b', 'B', 'c', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'p', 's', 'x', 'X' 控制呈现格式

怎么样,是不是通过上表的说明,大家对这个格式控制有了一个初步的理解呢?下面我们继续展开,深入讲讲 alignsigntype参数取值的具体意义。

表格1: align 参数说明

align 说明
'<' 强制左对齐。若长度不足 width,则从字符串末尾进行填充。
'>' 强制右对齐。若长度不足 width,则从字符串开始进行填充。
'=' 仅用于数值类型。若长度不足 width,则从 sign 或前缀之后、数字开始之前进行填充。
'^' 强制居中对齐。若长度不足 width,则在字符串两侧同时进行填充。

表格2: sign 参数说明

sign 说明
'+' 针对正数显式添加 '+' 号,如 "+123"。
'-' 针对负数显式添加 '-' 号,如 "-123";针对正数不添加符号,如 "123"。这是默认选项。
'空格' 针对正数在头部添加一个空格,如 " 123";针对负数添加 '-' 号,如 "-123"。

表格3: type 参数说明

type 说明 '#' 作用
's' 按原始字符串输出,仅用于字符串。
'c' 按原始字符输出,仅用于 char8_t, char16_t, char32_t, char, wchar_t 类型。
'b', 'B' 按二进制输出,仅用于整数类型,如 "1010"。 'b' 添加 "0b"; 'B' 添加 "0B"
'd' 按十进制输出,仅用于整数类型,如 "12345"。
'o' 按八进制输出,仅用于整数类型,如 "10"。 添加 "0"。
'x', 'X' 按十六进制输出,仅用于整数类型。'x' 输出小写,'X' 输出大写。 'x' 添加 "0x";'X' 添加 "0X"
'n' 意义同 'd',但在其基础上,根据本地语言设置,添加十进制的分隔符,如:"1,000,000"。
'a', 'A' 按十六进制输出,并根据 precision 保留小数,仅用于浮点类型。'a' 输出小写,'A' 输出大写。
'e', 'E' 按科学计数法输出,仅用于浮点类型。若 precision 省略,则默认为 6。'e' 输出小写,'E' 输出大写。
'f', 'F' 按十进制输出,并根据 precision 保留小数,仅用于浮点类型。若 precision 省略则默认为 6。'f' 输出小写,'F' 输出大写。
'g', 'G' 按十进制 + 科学计数法方式输出。若 precision 省略则默认为 6。'g' 输出小写,'G' 输出大写。
'n' 意义同 'g',但在其基础上,根据本地语言设置,添加十进制的分隔符,如 "1,000.456"。
'p' 按十六进制输出指针值,仅用于指针类型,如 "FFFFFFFF"。 添加 "0x"

写到这,不得不感叹,这次添加进标准的格式化函数还是非常完备的,考虑到了各种类型的格式化。理论用于实际,让我们看看一些实例吧。

// 高级用法:格式化控制符
char c = 120;
auto s0 = std::format("{:6}", 42);      // s0 == "    42"
auto s1 = std::format("{:6}", 'x');     // s1 == "x     "
auto s2 = std::format("{:*<6}", 'x');   // s2 == "x*****"
auto s3 = std::format("{:*>6}", 'x');   // s3 == "*****x"
auto s4 = std::format("{:*^6}", 'x');   // s4 == "**x***"
auto s6 = std::format("{:6d}", c);      // s6 == "   120"
auto s7 = std::format("{:=+06d}", c);   // s7 == "+00120"
auto s8 = std::format("{:0=#6x}", 0xa); // s8 == "0x000a"
auto s9 = std::format("{:6}", true);    // s9 == "true  "

示例3:std::format_to 的用法

std::format_to 函数主要用于容器类型,如 std::vector<T> 的格式化添加值。

#include <vector>
#include <format>
#include <string>int main()
{std::vector<std::string> data;for (size_t i = 0; i < 100; i++){std::format_to(std::back_inserter(data), "我的工号是:{} ", i);}
}

其中格式字符串的用法等同于 std::format 函数,可参考上述有关内容。

std::source_location

这是一个比较实用的特性。它为标准库新增了一个元数据类 std::source_location,可为用户提供当前代码的上下文信息。该类的定义如下所示。

namespace std
{struct source_location{constexpr source_location() noexcept;constexpr uint_least32_t line() const noexcept;constexpr uint_least32_t column() const noexcept;constexpr const char* file_name() const noexcept;constexpr const char* function_name() const noexcept;static consteval source_location current() noexcept;};
}

示例:

#include <source_location>
#include <format>
#include <iostream>void foo()
{// Get the location of this line.auto loc = std::source_location::current();std::cout << std::format("Line: {}, Column: {}, Function: {}, File: {}", loc.line(), loc.column(), loc.function_name(), loc.file_name()) << std::endl;
}

概念(Concepts)采用标准库命名规范

这个特性是指原本采用 Pascal 命名法的概念,在这次会议中投票通过改为与标准库一致的小写下划线命名法。如:

std::Invocable 改为 std::invocable

std::ConvertibleTo 改为 std::convertible_to

std::EqualityComparable 改为 std::equality_comparable

等等

总结

由于这次投票通过的特性还是比较多的,我只挑选了几个有代表性的展开,其他的就不再一一赘述。(毕竟肉翻还是很费脑细胞的233)。感兴趣的同学可以去看我在引言中的原文链接查阅。由于本人水平有限,若有瑕疵,在所难免。欢迎大家拍砖指正!

转载于:https://my.oschina.net/u/4173234/blog/3080199

C++标准委员会7月科隆会议中投票通过的特性相关推荐

  1. 1996 年 3 月. IEEE 成立了 802.3z 工作组开始制定 1000Mb/s 标准。下列千兆以太网中不属于该标准的是(19)【答案】C

    1996 年 3 月. IEEE 成立了 802.3z 工作组开始制定 1000Mb/s 标准.下列千兆以太网中不属于该标准的是(19) (19)A.1000 Base-SX B.1000 Base- ...

  2. 电信科学技术第五研究所怎么样_刘有成先生百年诞辰纪念会暨兰州大学功能有机分子化学国家重点实验室第七届学术委员会第五次会议在兰州大学召开 - 实验室动态 - 实验室动态...

    2020年11月6日,刘有成先生百年诞辰纪念会暨兰州大学功能有机分子化学国家重点实验室第七届学术委员会第五次会议在兰州大学城关校区(西区)逸夫科学馆学术报告厅顺利召开.出席此次会议的专家领导有中科院理 ...

  3. 清华大学计算机学科顾问委员会第三次会议举行

    9月21日上午,清华大学计算机学科顾问委员会(以下简称"顾问委员会")第三次会议在主楼接待厅举行.全国政协第十二届委员会副主席.顾问委员会主席陈元,校党委书记.校务委员会主任陈旭, ...

  4. VR/AR标准委员会成立,宣布全新的标准OpenXR

    Khronos集团在今天早些时候宣布了开放VR/AR标准委员会--OpenXR工作组.这一组织也将会由世界领头羊VR/AR公司的代表组成. 而宣布的公司中包括:Facebook子公司Oculus.va ...

  5. 在fomc会议中建模主题趋势

    补习班(HANDS-ON TUTORIAL) The Federal Open Market Committee (FOMC) is an important part of the US finan ...

  6. 凝心聚力,携“源”出海:开源社顾问委员会2023年第一季度会议圆满举办!

    2023 年 3 月 25 日,开源社顾问委员会(以下简称"顾问委员会")第一季度会议在北京圆满召开.这是顾问委员会自 2018 年成立以来的第 17 次全体委员会议. 为增进顾问 ...

  7. VR/AR标准委员会成立OpenXR工作组:Oculus、Valve领头

    本文转自:52VR.com  VR资讯  http://www.52vr.com/article-822-1.html Khronos集团在今天早些时候宣布了开放VR/AR标准委员会--OpenXR工 ...

  8. C11标准委员会成员解读C语言新标准

    导读:C语言国际标准新的新草案之前已经公布,新标准提高了对C++的兼容性,并将新的特性增加到C语言中.此外支持多线程的功能也受到了开发者的关注,基于ISO/IEC TR 19769:2004规范下支持 ...

  9. 敏捷开发中“可运行软件”的评审标准(兼谈敏捷开发中的迭代中期质量控制)...

    软件"可运行"了就可以评审且通过了?这是个问题. 在多年前参加Scrum Master培训的时候,老师拿出一个很好的表格,每行是一个故事,每列大致如此: 编码完成 功能测试 单元测 ...

  10. AI人才创新发展联盟(AIHIA)执行委员会一届一次会议胜利闭幕

    2023年1月8日晚21点30分,AI人才创新发展联盟(AIHIA)(以下简称"联盟")执行委员会一届一次会议(以下简称"本次会议")胜利闭幕.因实际因素的影响 ...

最新文章

  1. 8.使用for循环和while循环遍历文件
  2. Python代码注释应该怎么写?
  3. SpringBoot集成Spring Security(二)注册 、密码加密、修改密码
  4. flink入门_Flink入门:读取Kafka实时数据流,实现WordCount
  5. 从搭建大数据环境说起,到执行WordCount所遇到的坑
  6. Java 表单提交下拉框_Java实现Layui的form表单动态绑定下拉框
  7. 据说,上海AI产业规模700亿,包揽全国1/3人才
  8. visual studio code .net 开发
  9. Charades数据集
  10. ubuntu屏幕取词词典
  11. 【UML】构件图(Component Diagram)
  12. Vue之filters传参问题
  13. 算法提高 金明的预算方案
  14. markdown 转word
  15. 笔记-项目干系人管理-控制干系人参与
  16. 拼死抢到一个猫爪杯,粉丝却说他想要这个?!(文末抢福利)
  17. 使用c语言实现的fifo程序,C语言实现标准FIFO
  18. RFID读卡器增量更新思路与代码实现
  19. 计算机操作系统期末复习,《计算机操作系统》期末复习课稿.docx
  20. 实现windows xp自动登录大法

热门文章

  1. html5文档加载前调用函数,html调用javascript外部文件显示函数未定义
  2. 认识机器视觉环形光源
  3. Methods of integrating data to uncover genotype–phenotype interactions 翻译
  4. 香港服务器到大陆各地的网络延迟大小
  5. 基于Java swing+mysql+eclipse的【图书管理系统】
  6. 项目开发中DEV、QAS、PRD是什么意思
  7. 【OpenCV】 300行写出全能扫描王
  8. java有哪些技术领域
  9. 微信公众号授权登录配置
  10. 得分——UVa1585