C++20标准中开始引入模块(module)的概念,用于解决传统的头文件包含机制在编译时间,工程代码组织等方面的问题,本文简要介绍C++20的模块机制及其使用说明或限制条件。
简介
C++20标准引入模块(Module)作为现代化的C++库和程序组件化的解决方案,模块可简单的类比为头文件(Header File)+翻译单元(translation unit),模块的源文件与导入该模块的翻译单元是独立编译的,因而编译过程中模块只需要编译一次。模块作为#include
头文件的替代方案可带来以下几个方面的优化:
- 编译时间(Compile-time):C++编译器编译处理源文件时,对其
#include
的头文件,编译器会预处理并解析该头文件的内容以积极递归处理该头文件中包括的其它头文件,导致当项目工程中的多个源文件包括某些相同的头文件时编译器会做大量的重复编译工作。 - 标识符隔离(Isolation):C++预处理器通过
#include
指令把头文件的内容直接包括进当前的源文件中,使得在多个不同的头文件中的相同的标识符产生冲突,用户需要重排#include
指令顺序或引入#undef
指令来避免冲突。 - 重复编码(Deduplication):使用头文件方式编写库或程序时,需要在头文件中提供声明(declaration),而在实现源文件中提供定义(definition),导致不必要的重复和冗余。
语法
模块声明(module declaration):Declares that the current translation unit is a module unit
[export] module <module-name> [: <module-partition-name>]+ ;
特殊模块声明:
module ; // starts a global module fragment module : private ; // starts a private module fragment
导出声明(export declaration):[导出模块内的变量、函数、类等]
export <declaration>
---
export { <declaration-seq>... }
e.g.,
export Module M;
export int I;
export struct S;
export class C;
export void fn();
export typedef S T;
export using T = C;
export static_assert(true); // Wrong
模块导入声明(module import declaration):[导入模块单元(module unit)、模块分区(module partition)、头文件单元(header unit)]
[export] import (<module-name> | <module-partition-name> | <header-file-name>)
e.g.,
import M;
import :P;
import M:P;
import <vector>
export
限制
-
export
不能导出具有内部链接(internal linkage)的C++实体(如静态变量或函数,定义在匿名命名空间中的变量或函数或类等),如: