重大变更(一):关于C++26的十大猜想

2023-10-29

你好,我是卢誉声。

在上一讲中,我们讨论了C++23带来的变化。由于C++23已经是冻结特性,所以我们讨论得非常具体。C++23作为“更好的C++20”,其本质是针对C++20进行改进和修补,所以涵盖的内容比较有限。

但是,作为继C++20之后的又一重大标准变更,C++26及其后续演进将会给我们带来诸多重量级特性。为了更好地理解C++标准的演进思路、掌握C++标准演进的底层逻辑,并一窥未来的变化,这一讲中,我们把视角转向C++26及其后续演进。

不过,由于C++26还处在提案阶段。所以,我们只能预测一下那些“大概率会进入C++26”的特性,也许其中一些特性会被推迟或发生改变,但并不影响我们分析C++标准演进的底层逻辑和未来。

好,就让我们从静态反射开始今天的内容。

静态反射

静态反射(static reflection),很有可能是C++26中即将引入的最为重量级的特性。但凡是了解何为反射机制,同时熟悉C++的人,看到这个特性时,估计会虎躯一震——什么?C++要支持反射?

但是我们需要冷静一下,这个特性的定语很重要,这个反射是“静态的”(static)。

对于反射的概念,还是很容易理解的,就是编程语言提供一套机制,帮助开发者在代码中获取类型的相关信息,比如类型名称、大小、类的成员、函数参数信息等等。它允许开发者在代码中,根据反射信息执行相应的操作,这让语言变得更加“动态”——也就是根据反射信息来确定代码如何执行。

其实早在C++98标准,在引入dynamic_cast和RTTI时,C++就允许开发者获取有限的运行时类型信息。但是,这些运行时类型信息非常贫乏,除了支持类型转换以外,并没有什么其他用处。而且,即便是这些有限的功能,也特别耗费C++的运行时资源,与C++自身的设计理念有些偏差。

不过,C++新提出的静态反射则大不相同。这个特性秉持了现代C++一以贯之的理念,在编译时获取并确定所有信息。所以说,这个静态反射也就和C++11之后引入的type_traits一样,可以在编译时获取所有的信息。并在编译时,通过模板和constexpr等方式完成相关计算。

静态反射标准的特性尚处于讨论阶段,不过已经有相关的TS(Technical specifications,即技术规范)。因此,我们来了解一下,在TS中是如何使用静态反射的?

首先,C++会提供一个新的关键字——reflexpr,用于获取一个符号的“元数据”。我们可以结合后面这个例子来理解。

#include <cstdint>
#include <experimental/reflect>
 
int main() {
    int32_t num = 0;
    
    using NumMeta = reflexpr(num);
 
    return 0;
}

你不用尝试运行这个例子——目前暂时还没有编译器支持它。我们关注点就在代码第7行,通过reflexpr获取了num的元数据。

我们需要知道,reflexpr返回的元数据并不是一个变量,而是一个类型,所以要用using或者typedef来为其定义一个别名,这样才能在后面使用。

那么获取到的类型别名要如何使用呢?我们继续看代码。

#include <string>
#include <iostream>
#include <experimental/reflect>
 
int main() {
    using Type1 = reflexpr(std::string);
    using Type2 = reflexpr(std::u8string);
 
    std::cout << std::experimental::reflect::get_name_v<Type2> << std::endl;
    static_assert(Type1 == "basic_string");
 
    std::cout << std::experimental::reflect::reflects_same_v<Type1, Type2> << std::endl;
 
    return 0;
}

获取到类型别名后,我们就可以使用C++提供的reflect工具函数,静态地获取关于类型别名的一切信息,比如代码第9行通过get_name_v获取了Type2的类型名称,第12行通过reflects_same_v判断两个类型是否相同。

由于静态反射的类型信息都存储在类型中,因此,reflect的工具都可以实现成工具类型或constexpr函数。所以,我们也可以在static_assert和模板参数中,配合C++ Concepts特性,通过模板实现针对不同类型细节执行不同的操作逻辑。

事实上,正是因为静态反射需要基于constexpr、static_assert和concept实现。因此,直到C++26之后,静态反射才可能成为备选的提案。

基于这些基础设施,C++的编译时计算会变得前所未有的强大。

此外,静态反射的TS还提供了面向反射元数据类型的一系列concept,这样我们就可以通过定义模板函数,完成更多的反射元数据的计算与判断。

可以说,如果C++26及其后续演进真的实现了静态反射TS,C++的编译器“动态”特性就基本完美了。

异步任务框架

从C++11开始,现代C++一直在试图扩展、完善并发任务管理,从基础的thread支持,到future、promise、async、并行算法,到C++20的协程,都在逐步完善C++标准库的并发任务支持。

C++11提供的thread解决了基于线程的并发任务的基础设置,通过atomic解决了细粒度的原子操作问题,通过mutex和信号量解决了线程同步问题,通过promise、future和async解决了并发任务的创建与基本调度问题。

但直到C++20为止,我们依然需要关注很多并发任务执行的细节问题,无法通过标准库解决并发任务的高层调度问题。比如后面这些问题。

  • 如何控制同时执行的并发任务数量。
  • 如何解决任务的错误重试机制。
  • 如何处理多个异步任务之间的串行、并行甚至条件调度。
  • 如何更方便地在两个并发任务中发送接收消息等等。

C++ Executors的目标就是解决这些问题,我们这就来说说executors中的概念与提供的能力。

第一个概念就是executor。

executor本质是一个concept,表示可以被execute和schedule等调度函数调用的类型,它可以是一个函数、仿函数,也可以是一个Lambda函数。

对于其他调度函数,它们通过调用executor来提交并发任务。假如说,我们需要通过线程池来执行任务,那么可以创建一个线程池对象,并从线程池对象中获取一个executor。

#include <string>
#include <iostream>
#include <execution>
 
int main() {
    using namespace std::execution;
    
    std::static_thread_pool pool(4);
    executor auto poolExecutor = pool.executor();
 
    execute(poolExecutor, [] { std::cout << "这是一个在线程池中执行的任务"; });
 
    return 0;
}

在代码第8行,定义了一个大小为4的线程池。接着,通过executor成员函数获取了一个可以在线程池中执行并发任务的executor。然后,调用execute函数,execute会调用poolExecutor将这个Lamba函数提交到线程池中执行。

这种情况下,executor帮我们屏蔽了提交并发任务的所有细节,为其他的任务调度函数提供通用的调度接口。当然executor只是一个抽象,所以底层实现并不一定是线程——我们同样可以将coroutine包装成executor,因此executor是一个通用的并发任务接口。

第二个重要的概念是sender/receiver。

虽然标准定义了通用的executor。但是,用于调用executor执行任务的execute函数,它的返回类型为void。因此,我们无法通过链式调用的形式将多个并发任务串联在一起执行,就更不用说完成一些更高级的并发任务连接了。

为此,标准提出了sender和receiver。sender是一个创建之后不会自动执行的调度任务,需要等到在它后面连接一个receiver之后,才会开始执行。当sender执行完成后,就会调用receiver约定的接口将数据传递给receiver,并开始执行receiver,标准中将receiver连接到sender后的函数就是connect,伪代码如下所示。

#include <string>
#include <iostream>
#include <execution>
 
int main() {
    sender auto snd = create_sender();
    receiver auto rec = create_receiver();
    std::execution::connect(snd, src);
 
    return 0;
}

那我们要如何实现链式调用呢?这时就需要引入通用异步算法这个概念了。

所谓通用异步算法,就是一个接收用户自定义任务作为sender的函数,该函数会调用connect将该sender与算法内部的一个receiver连接,然后包装成一个新的sender返回给调用方,这样调用方就可以将这个sender传给下一个通用算法或者connect其他的计算任务,最终形成链式调用。标准库中future/promise的then就是通过这种方式实现的。

最后一个重要的概念是scheduler。

我们可能经常会碰到一种情况,就是有多个并发任务,使用相同的sender。如果直接链接sender对象和多个任务。很有可能会产生竞争问题。

为此,C++标准提出了scheduler。它主要通过schedule函数返回,该函数会返回一个新的sender作为内部sender的工厂,这样即使将同一个scheduler连接到多个receiver,也不会引发数据竞争问题。

网络库

接下来,我为你介绍一个“有些可能”推出的标准网络库——networking。我为什么说“有些可能”呢?这是因为标准网络库已经在标准中,被推迟了无数次

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重大变更(一):关于C++26的十大猜想 的相关文章

  • 如何使用 Java 中的 Web 服务(例如 Axis2)发送复杂对象的数组或集合?

    我对 SOAP Web 服务还比较陌生 虽然我完成了一些较小的 Web 服务项目 但我偶然从来不需要返回 或用作参数 复杂 对象的数组或集合 当我尝试这样做时 根据我的 SOAP 绑定风格 我会得到不同的奇怪行为 当我使用RPC 文字 我可
  • Java AES 128 加密方式与 openssl 不同

    我们遇到了一种奇怪的情况 即我们在 Java 中使用的加密方法会向 openssl 生成不同的输出 尽管它们在配置上看起来相同 使用相同的键和 IV 文本 敏捷的棕色狐狸跳过了懒狗 加密为 Base64 字符串 openssl A8cMRI
  • wait() 在游戏中如何工作?

    在 playframework 的文档中here http www playframework org documentation 1 2 1 asynchronous已写 public static void loopWithoutBlo
  • JavaFX 中具有自定义内容的 ListView

    How i can make custom ListView with JavaFx for my app I need HBox with image and 2 Labels for each line listView 您可以通过查看
  • 当从服务类中调用时,Spring @Transactional 不适用于带注释的方法

    在下面的代码中 当方法内部 是从内部调用的方法外部 应该在交易范围内 但事实并非如此 但当方法内部 直接从调用我的控制器class 它受到事务的约束 有什么解释吗 这是控制器类 Controller public class MyContr
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 如何模拟从抽象类继承的受保护子类方法?

    如何使用 Mockito 或 PowerMock 模拟由子类实现但从抽象超类继承的受保护方法 换句话说 我想在模拟 doSomethingElse 的同时测试 doSomething 方法 抽象超类 public abstract clas
  • 在 Netbeans 8 上配置 JBoss EAP 的问题

    我已经下载了 JBoss EAP 7 并正在 Netbeans 8 上配置它 我已经到达向导 实例属性 其中要求从选择框中选择 域 当我打开选择框时 它是空的 没有什么可以选择的 因此 完成 按钮也处于非活动状态 这使得无法完成配置 我通过
  • 将 SignedHash 插入 PDF 中以进行外部签名过程 -workingSample

    遵循电子书第 4 3 3 节 PDF 文档的数字签名 https jira nuxeo com secure attachment 49931 digitalsignatures20130304 pdf 我正在尝试创建一个工作示例 其中 客
  • Java 中的“Lambdifying”scala 函数

    使用Java和Apache Spark 已用Scala重写 面对旧的API方法 org apache spark rdd JdbcRDD构造函数 其参数为 AbstractFunction1 abstract class AbstractF
  • (转)如何使用toml文件?

    正如标题 我想知道如何使用 golang 中的 toml 文件 在此之前 我展示了我的 toml 示例 这样对吗 datatitle enable true userids 12345 67890 datatitle 12345 prop1
  • 编辑文件名在 JComboBox 中的显示方式,同时保持对文件的访问

    我对 Java 很陌生 对堆栈溢出也很陌生 我正在尝试利用 JMF API 创建一个用 Java 编码的简单媒体播放器 到目前为止 我已经能够设置一个简单的队列 播放列表来使用JComboBox called playListHolder
  • IntelliJ - 调试模式 - 在程序内存中搜索文本

    我正在与无证的第三方库合作 我知道有一定的String存储在库深处的某个字段中的某处 我可以预测的动态值 但我想从库的 API 中获取它 有没有一种方法可以通过以下方式进行搜索 类似于全文搜索 full程序内存处于调试模式并在某个断点处停止
  • Struts 2 + Sitemesh 3 集成 - FreemarkerDecoratorServlet 中的 NPE

    我将 Struts 2 版本 2 3 14 3 与 Sitemesh 3 版本 3 0 alpha 2 一起使用 并且在某些情况下遇到 NullPointerException 首先 这是我的 web xml 中的 struts2 site
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • 我可以创建自定义 java.* 包吗?

    我可以创建一个与预定义包同名的自己的包吗在Java中 比如java lang 如果是这样 结果会怎样 这难道不能让我访问该包的受保护的成员 如果不是 是什么阻止我这样做 No java lang被禁止 安全管理器不允许 自定义 类java
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • 如何从 Maven 存储库引用本机 DLL?

    如果 JAR 附带 Maven 存储库中的本机 DLL 我需要在 pom xml 中放入什么才能将该 DLL 放入打包中 更具体地举个例子Jacob http search maven org artifactdetails 7Cnet s
  • 调整添加的绘制组件的大小和奇怪的摆动行为

    这个问题困扰了我好几天 我正在制作一个特殊的绘画程序 我制作了一个 JPanel 并添加了使用 Paint 方法绘制的自定义 jComponent 问题是 每当我调整窗口大小时 所有添加的组件都会 消失 或者只是不绘制 因此我最终会得到一个
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import

随机推荐

  • SpringCloud组件之断路器Hystrix(hoxton版本)

    1 Hystrix 简介 在微服务架构中 根据业务来拆分成一个个的服务 服务与服务之间可以相互调用 RPC 在Spring Cloud可以用RestTemplate Ribbon和Feign来调用 为了保证其高可用 单个服务通常会集群部署
  • WinForm中如何实现panel和SplitContainer相结合进行布局呢

    相信大家都会在winform应用程序中进行布局 通常我们也会使用一下这种布局 如图 以上布局分别采用了Panel 黑色区域 和SplitContainer控件 白色区域 这布局相信大家耳熟能详了 比如VS2010不就是典型这样布局吗 但是需
  • 西瓜书之误差逆传播公式推导、源码解读及各种易混淆概念

    关键词 反向传播 BP caffe源码 im2col 卷积 反卷积 上池化 上采样 公式推导 以前看到一长串的推导公式就想直接跳过 今天上午莫名有耐心 把书上的公式每一步推导自己算一遍 感觉豁然开朗 遂为此记 sigmoid函数求导比rel
  • 最小二乘拟合,L1、L2正则化约束

    最小二乘法 又称最小平方法 是一种数学优化技术 它通过最小化误差的平方和寻找数据的最佳函数匹配 利用最小二乘法可以简便地求得未知的数据 并使得这些求得的数据与实际数据之间误差的平方和为最小 从维基百科中摘取的最小二乘的拟合曲线 解法 其中Y
  • TSI系统测量参数之:热膨胀

    一 TSI系统测量参数 1 轴向位移 2 盖振或瓦振 3 偏心 4 键相 5 零转速 6 轴向振动 7 相对热膨胀 胀差 8 绝对热膨胀 缸胀 二 各参数作用 4 绝对热膨胀 汽轮机在开机过程中由于受热使其汽缸膨胀 如果膨胀不均匀就会使汽缸
  • 辅助汇编学习记录2

    通用寄存器 EAX EBX ECX EDX ESI EDI ESP EBP 它 们 的低 16 位就是 8086 的 AX BX CX DX SI DI SP BP 它们的含义如下 EAX 累加器 EBX 基址寄存器 Base ECX 计数
  • C语言中的短路现象

    短路现象1 比如有以下表达式 a b c 只有a为真 非0 才需要判断b的值 只有a和b都为真 才需要判断c的值 举例 求最终a b c d的值 main int a b c d a 0 b 1 c 2 d a b c printf a d
  • 桥接模式与策略模式的区别

    文章转载自 http www blogjava net wangle archive 2007 04 25 113545 html 桥接 Bridge 模式是结构型模式的一种 而策略 strategy 模式则属于行为模式 以下是它们的UML
  • 【生信】全基因组关联分析(GWAS)原理

    生信 全基因组关联分析 GWAS 原理 文章的文字 图片 代码部分 全部来源网络或学术论文 文章会持续修缮更新 仅供大家学习使用 目录 生信 全基因组关联分析 GWAS 1 前提知识介绍 1 1 最小二乘法 1 2 GWAS的数学原理 1
  • 【笔记】软件测试06——Web自动化

    阅读 石墨文档 七 web自动化测试 GUI自动化测试学习内容 了解自动化测试的相关概念 掌握Selenium Webdriver常用API 掌握自动化测试中的元素定位方法 掌握自动化测试中的元素操作 掌握自动化测试断言操作 掌握unitt
  • 使用合宙Air700e点亮一个LED灯(lua)

    相信很多朋友和我一样都团了9 9的air700e开发板 我猜有很多朋友都是买来吃灰的吧 包括我也是一样 网络上的相关资料并不是很丰富 对于像我这样的小白来说不是很友好 今天给大家演示一下使用air700e演示点灯大法 通常我们见到使用通信模
  • HTML常用标签合集

    今天来讲讲有关html的常用标签 嘎嘎有用 嘎嘎好用 目录 HTML常用标签 一 首先来讲第一种 标题标签 h1 h6 二 第二种 段落标签 p 三 第三种 hgroup标签 四 第四种 强调标签 em strong 五 第五种 引用标签
  • 关于Android向前兼容和向后兼容问题的理解

    最近在和别人交流的的时候涉及到Android开发向前兼容和向后兼容的问题一头雾水 于是乎定下心来好好研究了下 虽然所知也只是些皮毛 但是也总比啥也不知道的好 所以在此总结 一 向前兼容 1 何谓向前兼容 google公司在不断的发步新的an
  • [译] 最佳安全实践:在 Java 和 Android 中使用 AES 进行对称加密

    原文地址 Security Best Practices Symmetric Encryption with AES in Java and Android 最佳安全实践 在 Java 和 Android 中使用 AES 进行对称加密 我将
  • 获取网络MP3真实地址

    MP3网站的歌曲都采用了不同的加密方法 直接从页面的源文件中是找不到其 MP3的网址的 以下有两个public class都可独立运行 只要将其构造方法更名为main方法就可以了 同时还需要在给出的JAVA源代码中找到 播放或下载代码 这一
  • 手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3-RestNet50-VGG16(附python源代码及数据库)——改变世界经典人工智能项目实战(一)手把手教学迁移学习

    手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3 RestNet50 VGG16 1 迁移学习简介 2 项目简介 3 糖尿病视网膜病变数据集 4 考虑类别不平衡问题 5 定义模型质量 6 定义损失函数 7 预处理图像
  • java输出json格式的文件超级详细简单!!!!

    话不多说直接上代码 package ram import com alibaba fastjson JSON import com alibaba fastjson serializer SerializerFeature import j
  • 基于java网上订餐网站系统

    通过网上西餐厅网上订餐管理系统这个平台 消费者足不出户就可以了解大量的西餐厅菜单信息 给消费者带来了极大的方便 网上西餐厅管理系统平台的主要功能包括菜单类别管理 菜单信息管理等 根据客户种类又可以划分成管理员客户和会员客户两种 本系统前台设
  • OSWatcher使用简介

    OSWatcher Black Box 简称OSW 是oracle提供的一个小但是非常有用的工具 它通过调用OS自己提供的命令来记录OS运行时的一些性能参数 比如CPU Memory Swap Network IO Disk IO相关的信息
  • 重大变更(一):关于C++26的十大猜想

    你好 我是卢誉声 在上一讲中 我们讨论了C 23带来的变化 由于C 23已经是冻结特性 所以我们讨论得非常具体 C 23作为 更好的C 20 其本质是针对C 20进行改进和修补 所以涵盖的内容比较有限 但是 作为继C 20之后的又一重大标准