C++20中的模块

news2025/1/23 14:56:29

      大多数C++项目使用多个翻译单元(translation units),因此它们需要在这些单元之间共享声明和定义(share declarations and definitions)。headers的使用在这方面非常突出。模块(module)是一种language feature,用于在翻译单元之间共享声明和定义它们是某些headers用例的替代方案。在C++20中,引入了模块的概念,以提高编译过程的效率并提供更好的代码组织和封装。模块允许开发人员将他们的代码分成单独的组件,每个组件都有自己的接口和实现,并根据需要导入它们。模块减少了与头文件相关的缺点,从而减少了编译时间

      模块与命名空间正交(Modules are orthogonal to namespaces)。

      语法如下:

export(optional) module module-name module-partition(optional) attr(optional); // Module declaration. Declares that the current translation unit is a module unit
export declaration // Export declaration. Export all namespace-scope declarations in declaration
export { declaration-seq(optional) } // Export declaration. Export all namespace-scope declarations in declaration-seq
export(optional) import module-name attr(optional); // Import declaration. Import a module unit
export(optional) import module-partition attr(optional); // Import declaration. Import a module partition
export(optional) import header-name attr(optional); // Import declaration. Import a header unit
module; // Starts a global module fragment
module : private; // Starts a private module fragment

      1.Module declarations:

      翻译单元可以具有模块声明,在这种情况下,它被视为模块单元。如果提供了模块声明,则必须是翻译单元的第一个声明(全局模块片段(fragment)除外)。每个模块单元都与模块声明中提供的模块名称(以及可选的分区(partition))相关联。模块单元是包含模块声明的源文件

      模块名称由一个或多个用点分隔的标识符组成(例如:mymodule、mymodule.mysubmodule、mymodule2...)。点没有内在含义,但它们被非正式地用于表示层次结构。

      声明中包含关键字export的模块单元称为模块接口单元(例如vs2022中后缀为.ixx文件,只编译一次,被编译成二进制表示);所有其他模块单元称为模块实现单元(例如vs2022中后缀为.cppm文件)。

      对于每个命名模块,必须有一个不指定模块分区的模块接口单元;此模块单元称为主模块接口单元。其导出的内容将在导入相应的命名模块时可用。

      2.Exporting declarations and definitions:

      模块接口单元可以导出声明(包括定义),这些声明可以被其他翻译单元导入。要导出声明,需在其前面加上export关键字,或者将其放在导出块内。

      3.Importing modules and header units:

      模块通过导入声明导入

      给定命名模块的模块接口单元中导出的所有声明和定义都将使用导入声明在翻译单元中可用。

      导入声明可以在模块接口单元中导出。

      在模块单元中,所有导入声明必须分组在模块声明之后和所有其他声明之前(In module units, all import declarations must be grouped after the module declaration and before all other declarations)。

      #include不应在模块单元中使用(全局模块片段之外),因为所有包含的声明和定义都将被视为模块的一部分。

      头文件单元是从头文件合成的单独翻译单元(A header unit is a separate translation unit synthesized from a header)。导入头文件单元将使其所有定义和声明都可访问。预处理器宏也是可访问的(因为导入声明可被预处理器识别)。

      4.Global module fragment:

      模块单元可以用全局模块片段作为前缀,当无法导入headers时可以使用它来包含headers。

      如果模块单元具有全局模块片段,则其第一个声明必须是module;。然后,全局模块片段中只能出现预处理指令。然后,标准模块声明标记全局模块片段的结束和模块内容的开始。

      5.Private module fragment:

      主模块接口单元可以以私有模块片段作为后缀,这允许将模块表示为单个翻译单元,而无需使模块的所有内容都可以被导入器(importers)访问。

      私有模块片段结束模块接口单元中可以影响其他翻译单元行为的部分。如果模块单元包含私有模块片段,它将是其模块的唯一模块单元。  

      6.Module partitions:

      模块可以有模块分区单元。它们是模块声明中包含模块分区的模块单元,模块分区以冒号:开头,位于模块名称之后。

      一个模块分区恰好代表一个模块单元(两个模块单元不能指定同一个模块分区)。它们仅在命名模块内部可见(命名模块之外的翻译单元不能直接导入模块分区)。

      模块分区可以由同名命名模块的模块单元导入。

      模块分区中的所有定义和声明对于导入模块单元而言都是可见的,无论是否导出。

      模块分区可以是模块接口单元(当其模块声明具有导出时)。

      7.Module ownership:

      一般而言,如果声明出现在模块单元中的模块声明之后,则声明将附加到该模块。

      如果实体(entity)的声明附加到命名模块,则该实体只能在该模块中定义。此类实体的所有声明都必须附加到同一模块。

      vs2022配置支持C++20模块步骤:配置属性

      (1).常规 --> C++语言标准:选择"ISO C++20标准(/std:c++20)"

      (2).C/C++ --> 常规 --> 扫描源以查找模块依赖关系:选择"是"

      (3).C/C++ --> 语言 --> 启用实验性的C++标准库模块:选择"是(/exprimental:module)"

      测试工程如下图所示:

      模块接口单元math_operations.ixx内容如下:

export module math_operations;

export namespace math_ {
	int add(int a, int b);
	int sub(int a, int b);
	int mul(int a, int b);
	int div(int a, int b);
}

      模块实现单元math_operations.cppm内容如下:

export module math_operations;

//#include <iostream> // error
import <iostream>; // import declaration

namespace {
	void error() // NOT be visible
	{
		std::cerr << "Error: the divisor cannot be 0" << std::endl;
	}

} // namespace

export namespace math_ {
	int add(int a, int b) { return a + b; }
	int sub(int a, int b) { return a - b; }
	int mul(int a, int b) { return a * b; }
	int div(int a, int b)
	{
		if (b == 0) {
			error();
			return 0;
		}

		return a / b;
	}
} // export namespace math_

      test_modules.cpp内容如下:

import math_operations; // import declaration
#include <iostream>
//import <iostream>; // ok

int main()
{
	constexpr int a{ 8 }, b{ 2 };
	std::cout << "add: " << math_::add(a, b)
		<< ", sub: " << math_::sub(a, b)
		<< ", mul: " << math_::mul(a, b)
		<< ", div: " << math_::div(a, b) << std::endl;

	std::cout << "div2: " << math_::div(a, 0) << std::endl;

	std::cout << "test finish" << std::endl;
	return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

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

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

相关文章

追问试面试系列:Dubbo

欢迎来到Dubbo系列,在面试中被问到Dubbo相关的问题时,大部分都是简历上写了Dubbo,或者面试官想尝试问问你对Dubbo是否了解。 本系列主要是针对面试官通过一个点就使劲儿往下问的情况。 面试官:说说你们项目亮点 好的面试官 我们这个项目的技术亮点在于采用了Spring Cloud…

正点原子imx6ull-mini-Linux驱动之Linux I2C 驱动实验(21)

I2C 是很常用的一个串行通信接口&#xff0c;用于连接各种外设、传感器等器件&#xff0c;在裸机篇已经对 I.MX6U 的 I2C 接口做了详细的讲解。本章我们来学习一下如何在 Linux 下开发 I2C 接口器件 驱动&#xff0c;重点是学习 Linux 下的 I2C 驱动框架&#xff0c;按照指定的…

人工智能深度学习系列—探索Jaccard相似度损失:图像分割领域的新利器

文章目录 1. 背景介绍2. Loss计算公式3. 使用场景4. 代码样例5. 总结 1. 背景介绍 在深度学习的各种应用中&#xff0c;图像分割是一项极具挑战性的任务。Jaccard相似度损失&#xff08;Jaccard Similarity Loss&#xff09;&#xff0c;又称为IoU损失&#xff08;Intersectio…

计算机基本理论与程序运行原理概述

目录 计算机的基本表示方法 计算机的组成 程序运行的原理 指令执行的流水线 编译原理 个人理解 面试题总结 计算机的基本表示方法 计算机系统使用高、低电平来表示逻辑1和0。数据在计算机中的存储、传输和处理均以二进制形式进行。数据通过总线作为电信号进行传输&…

Es6常用的一些数组处理方法

在平时的开发中&#xff0c;我们很多时候用到数组结构数据&#xff0c;那么如何高效处理数组是可以提高开发效率的&#xff0c;现在越来越多人使用es6&#xff0c;那么它的很多方法简化了我们对数据的操作&#xff0c;比如以前数组循环用for循环写比较多的代码&#xff0c;现在…

HTML-07.表格标签

一、要制作的表格如下 二、代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格标签<…

探索数据结构:二叉搜索树的递归与非递归实现

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 二叉搜索树的介绍 二插入搜索树&#xff08;Binary Search Tree&…

第16课 Scratch入门篇:师生问候-广播版

师生问候-广播版 故事背景&#xff1a; 上节课我们完成了师生问候功能&#xff0c;指令罗列的蛮多&#xff0c;写起来很麻烦&#xff0c;而且阅读起来不容易理解&#xff0c;这节课我们把上节课内容进行优化&#xff0c;引入一个新的指令-广播&#xff0c;广播相当于一个事件的…

DFS之迭代加深+双向DFS+IDA*

迭代加深&#xff1a; 搜索范围一层一层扩大&#xff0c;可以快速某些分支比较深&#xff0c;但是答案比较浅的问题。 https://www.acwing.com/problem/content/172/ 通过观察可以发现&#xff1a; 1.搜索时最坏情况可能搜到100层&#xff0c;比较深&#xff0c;但是答案应…

【Javax.Validation】✈️整合 SpringBoot 实现运行时的参数校验

目录 &#x1f44b;前言 &#x1f440;一、Validation 依赖 &#x1f4eb;二、常见注解 2.1 不需要指定注解参数 2.2 需要声明注解参数 &#x1f49e;️三、项目测试注解使用 3.1 依赖引入 3.2 实体类创建 3.3 创建对外接口 3.4 模拟请求 &#x1f331;四、章末 &#x1f…

RSS 2024 清华大学交叉院高阳提出高效的机器人操作技能学习方法

机器人掌握一项新技能需要几步&#xff1f; 一般来说&#xff0c;在传统机器学习方法中&#xff0c;通常使用演示学习的方式教会机器人掌握新技能&#xff0c;然而&#xff0c;收集高质量的演示数据成本高且耗时&#xff0c;一定程度上影响了机器人技能学习进度。尽管视频作为…

⭕️【论文阅读】《Interactive Class-Agnostic Object Counting》

[2309.05277] Interactive Class-Agnostic Object Counting (arxiv.org) code&#xff1a; cvlab-stonybrook/ICACount: [ICCV23] Official Pytorch Implementation of Interactive Class-Agnostic Object Counting (github.com) 目录 Abstract Abstract 我们提出了一个新…

linux学习记录(一)--------目录及文件操作

文章目录 前言Linux目录及文件操作1.Linux目录结构2.常用的Linux命令3.vi编辑器的简单使用4.vi的两个模式 前言 小白学习linux记录有错误随时指出~ Linux目录及文件操作 Linux采用Shell命令->操作文件 1.Linux目录结构 根目录&#xff1a;/ 用户目录&#xff1a;~或者/ho…

float转uint8_t数组

float类型在x64中占4字节&#xff0c;需要占据uint8_t数组大小4字节 数据float类型3.14&#xff0c;在内存中4字节地址应该为0x4048f5c3 如果直接使用memcpy内存复制&#xff0c;0xc3会放在数组下标小的位置

〖任务1〗ROS2 jazzy Linux Mint 22 安装教程

前言&#xff1a; 本教程在Linux系统上使用。 目录 一、linux安装二、linux VPN安装三、linux anaconda安装&#xff08;可选&#xff09;四、linux ROS2 安装五、rosdep init/update 解决方法六、安装GUI 一、linux安装 移动硬盘安装linux&#xff1a;[LinuxToGo教程]把ubunt…

代码随想录算法训练营第43天|LeetCode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

1. LeetCode 300.最长递增子序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-increasing-subsequence/description/ 文章链接&#xff1a;https://programmercarl.com/0300.最长上升子序列.html 视频链接&#xff1a;https://www.bilibili.com/video/BV1ng411J…

进阶SpringBoot之 Spring 官网或 IDEA 快速构建项目

SpringBoot 就是一个 JavaWeb 的开发框架&#xff0c;约定大于配置 程序 数据结构 算法 微服务架构是把每个功能元素独立出来&#xff0c;再动态组合&#xff0c;是对功能元素的复制 这样做可以节省调用资源&#xff0c;每个功能元素的服务都是一个可替代、可独立升级的软…

从地铁客流讲开来:超一线城市的客运量特征

这篇我们把视角聚焦在四大超一线城市&#xff0c;北上广深&#xff0c;我们来看看这些城市地铁客运量的异同&#xff0c;这里放一个背景2024年6月8日—6月10日是我国农历的端午节&#xff0c;我们看图说话&#xff0c;相同的特征&#xff1a;1.四大一线城市客流都在周五达到客运…

数学建模--蒙特卡罗随机模拟

目录 蒙特卡罗方法的基本原理 蒙特卡罗方法在优化中的应用 蒙特卡罗方法的优势与局限 优势 局限 典型应用案例 Python代码示例 ​编辑 结论 蒙特卡罗方法在数学建模中的具体应用案例有哪些&#xff1f; 如何改进蒙特卡罗方法以提高计算效率和精度&#xff1f; 蒙特…

如何使你的mermaid流程图里的某一段文字加粗、变斜、成为上下标……

目录 参考的链接开头1.加粗&#xff0c;*斜体*与下划线2.标记,~~删除线~~与^上^~下~标3.代码片与标题4.注释与蓝色链接5.其</q>他 东西 结尾 参考的链接 HTML标签列表(按字母排序)和HTML标签列表(按功能排序) 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们…