打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C 20最新进展:移除合约(Contracts)、新增类模板参数推导优化和constinit关键字...

上周 C++ 标准委员会在科隆举行了7月会议(WG21)。会议中重点针对 C++20 标准已经投票通过的特性进行了若干修正,并对一些草案进行了讨论和投票。相比上次会议,通过了一些新的草案。

会议报告请访问:
《Trip Report: C++ Standards Meeting in Cologne, July 2019》

  • 合约(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。

示例:

constchar* g{ return'运行时初始化'; }
constexprconstchar* 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
enumclasschina_railway
{
cr400af,
cr400bf,
cr200j
};
用法1:
usingenum china_railway;
constexprauto train_type = cr400af;
用法2:
structfoo
{
// 引入枚举成员。
usingenum china_railway;
};
voidgeek
{
foo f;
auto a = f.cr400af; // 使用类实例,合法
auto b = foo::cr200j; // 使用类名,合法
}
用法3:
using china_fuxing_trains = china_railway;
using rubbish = china_railway::cr200j; // 枚举值别名
constexprauto type = china_fuxing_trains::cr400bf;
constexprauto 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::formatstd::format函数支持高级格式化控制。它使用格式控制表达式进行格式化输出。标准格式控制表达式的形式如下所示。
'{[arg_index]:[[fill]align][sign]['#']['0'][width]['.' precision][type]}'
说明:上式中的方括号代表为可选参数。
怎么样,是不是通过上表的说明,大家对这个格式控制有了一个初步的理解呢?下面我们继续展开,深入讲讲alignsigntype参数取值的具体意义。表格1:align参数说明
表格2:sign参数说明
表格3:type参数说明
写到这,不得不感叹,这次添加进标准的格式化函数还是非常完备的,考虑到了各种类型的格式化。理论用于实际,让我们看看一些实例吧。
// 高级用法:格式化控制符
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_tostd::format_to的格式化添加值。
#include <vector>
#include <format>
#include <string>
intmain
{
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,可为用户提供当前代码的上下文信息。该类的定义如下所示。
namespacestd
{
structsource_location
{
constexprsource_locationnoexcept;
constexpr uint_least32_t lineconstnoexcept;
constexpr uint_least32_t columnconstnoexcept;
constexprconstchar* file_nameconstnoexcept;
constexprconstchar* function_nameconstnoexcept;
static consteval source_location currentnoexcept;
};
}
示例:
#include <source_location>
#include <format>
#include <iostream>
voidfoo
{
// 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改为

等等

总结

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

按照计划的发布进度,C++20 预计将于明年夏季推出。

开源中国征稿啦!

开源中国 www.oschina.net 是目前备受关注、具有强大影响力的开源技术社区,拥有超过 400 万的开源技术精英。我们传播开源的理念,推广开源项目,为 IT 开发者提供一个发现、使用、并交流开源技术的平台。

现在我们开始对外征稿啦!如果你有优秀的技术文章想要分享,热点的行业资讯需要报道等等,欢迎联系开源中国进行投稿。

这款数据库将企业版功能100%开源还不收费,why?

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C++14新特性
Effective Modern C++笔记汇总
C 17 中那些值得关注的特性
全网首发!!C 20新特性全在这一张图里了
C++14新特性的所有知识点全在这儿啦
深入探索C++20的重要特性:从模块化到协程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服