You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Modules in C++20 provide a modern alternative to header files.
6
6
---
7
7
# Overview of modules in C++
8
8
9
-
C++20 introduces *modules*, a modern solution that turns C++ libraries and programs into components. A *module* is a set of source code files that are compiled independently of the source files (or more precisely, the [translation units](https://wikipedia.org/wiki/Translation_unit_(programming)) that import them). Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and nonexported names declared in a module aren't visible outside the module. They have no effect on the compilation of the translation unit that imports the module. You can import modules in any order without concern for macro redefinitions. Declarations in the importing translation unit don't participate in overload resolution or name lookup in the imported module. After a module is compiled once, the results are stored in a binary file that describes all the exported types, functions, and templates. The compiler can process that file much faster than a header file. And, the compiler can reuse it every place where the module is imported in a project.
9
+
C++20 introduces *modules*. A *module* is a set of source code files that are compiled independently of the source files (or more precisely, the [translation units](https://wikipedia.org/wiki/Translation_unit_(programming)) that import them.
10
+
11
+
Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times, sometimes significantly. Macros, preprocessor directives, and nonexported names declared in a module aren't visible outside the module. They have no effect on the compilation of the translation unit that imports the module. You can import modules in any order without concern for macro redefinitions. Declarations in the importing translation unit don't participate in overload resolution or name lookup in the imported module. After a module is compiled once, the results are stored in a binary file that describes all the exported types, functions, and templates. The compiler can process that file much faster than a header file. And, the compiler can reuse it every place where the module is imported in a project.
10
12
11
13
You can use modules side by side with header files. A C++ source file can `import` modules and also `#include` header files. In some cases, you can import a header file as a module, which is faster than using `#include` to process it with the preprocessor. We recommend that you use modules in new projects rather than header files as much as possible. For larger existing projects under active development, experiment with converting legacy headers to modules. Base your adoption on whether you get a meaningful reduction in compilation times.
12
14
@@ -43,11 +45,13 @@ import std.core;
43
45
import std.regex;
44
46
```
45
47
46
-
To consume the Microsoft Standard Library modules, compile your program with [`/EHsc`](../build/reference/eh-exception-handling-model.md) and [`/MD`](../build/reference/md-mt-ld-use-run-time-library.md) options.
48
+
To consume the Microsoft Standard Library modules, compile your program with the [`/EHsc`](../build/reference/eh-exception-handling-model.md) and [`/MD`](../build/reference/md-mt-ld-use-run-time-library.md) options.
47
49
48
50
## Example
49
51
50
-
The following example shows a simple module definition in a source file called *`Example.ixx`*. The *`.ixx`* extension is required for module interface files in Visual Studio. In this example, the interface file contains both the function definition and the declaration. However, you can also place the definitions in one or more separate module implementation files, as shown in a later example. The `export module Example;` statement indicates that this file is the primary interface for a module called `Example`. The **`export`** modifier on `f()` indicates that this function is visible when another program or module imports `Example`. The module references a namespace `Example_NS`.
52
+
The following example shows a simple module definition in a source file called *`Example.ixx`*. The *`.ixx`* extension is required for module interface files in Visual Studio. In this example, the interface file contains both the function definition and the declaration. However, you can also place the definitions in one or more separate module implementation files, as shown in a later example.
53
+
54
+
The `export module Example;` statement indicates that this file is the primary interface for a module called `Example`. The **`export`** modifier on `f()` indicates that this function is visible when another program or module imports `Example`.
51
55
52
56
```cpp
53
57
// Example.ixx
@@ -67,7 +71,7 @@ namespace Example_NS
67
71
}
68
72
```
69
73
70
-
The file *`MyProgram.cpp`* uses the **`import`**declaration to access the name that is exported by `Example`. The name `Example_NS` is visible here, but not all of its members. Also, the macro `ANSWER` isn't visible.
74
+
The file *`MyProgram.cpp`* uses **`import`** to access the name exported by `Example`. The namespace name `Example_NS` is visible here, but not all of its members because they aren't exported. Also, the macro `ANSWER` isn't visible because macros aren't exported.
71
75
72
76
```cpp
73
77
// MyProgram.cpp
@@ -109,64 +113,68 @@ The `import` declaration can appear only at global scope.
109
113
110
114
## Implementing modules
111
115
112
-
A *module interface* exports the module name and all the namespaces, types, functions, and so on, that make up the public interface of the module. A *module implementation* defines the things exported by the module. In its simplest form, a module can consist of a single file that combines the module interface and implementation. You can also put the implementation in one or more separate module implementation files, similar to how *`.h`* and *`.cpp`* files do it.
116
+
A *module interface* exports the module name and all the namespaces, types, functions, and so on, that make up the public interface of the module.\
117
+
A *module implementation* defines the things exported by the module.\
118
+
In its simplest form, a module can be a single file that combines the module interface and implementation. You can also put the implementation in one or more separate module implementation files, similar to how *`.h`* and *`.cpp`* files do it.
113
119
114
-
For larger modules, you can split parts of the module into submodules called *partitions*. Each partition consists of a module interface file that exports a module partition name. A partition may also have one or more partition implementation files. The module as a whole has one *primary module interface*, which is the public interface of the module and may export the partition interfaces.
120
+
For larger modules, you can split parts of the module into submodules called *partitions*. Each partition consists of a module interface file that exports the module partition name. A partition may also have one or more partition implementation files. The module as a whole has one *primary module interface*, which is the public interface of the module. It can export the partition interfaces, if desired.
115
121
116
122
A module consists of one or more *module units*. A module unit is a translation unit (a source file) that contains a module declaration. There are several types of module units:
117
123
118
-
- A *module interface unit*is a module unit that exports a module name or module partition name. A module interface unit has `export module` in its module declaration.
119
-
120
-
- A *module implementation unit*is a module unit that doesn't export a module name or module partition name. As the name implies, it implements a module.
121
-
122
-
- A *primary module interface unit*is a module interface unit that exports the module name. There must be one and only one primary module interface unit in a module.
124
+
- A *module interface unit* exports a module name or module partition name. A module interface unit has `export module` in its module declaration.
125
+
- A *module implementation unit* doesn't export a module name or module partition name. As the name implies, it implements a module.
126
+
- A *primary module interface unit*exports the module name. There must be one and only one primary module interface unit in a module.
127
+
- A *module partition interface unit* exports a module partition name.
128
+
- A *module partition implementation unit*has a module partition name in its module declaration, but no `export` keyword.
123
129
124
-
- A *module partition interface unit* is a module interface unit that exports a module partition name.
125
-
126
-
- A *module partition implementation unit* is a module implementation unit that has a module partition name in its module declaration, but no `export` keyword.
127
-
128
-
The **`export`** keyword is used in interface files only. An implementation file can **`import`** another module, but can't **`export`** any names. Implementation files can have any extension.
130
+
The **`export`** keyword is only used in interface files. An implementation file can **`import`** another module, but it can't **`export`** any names. Implementation files can have any extension.
129
131
130
132
## Modules, namespaces, and argument-dependent lookup
131
133
132
-
The rules for namespaces in modules are the same as in any other code. If a declaration within a namespace is exported, the enclosing namespace (excluding nonexported members) is also implicitly exported. If a namespace is explicitly exported, all declarations within that namespace definition are exported.
134
+
The rules for namespaces in modules are the same as any other code. If a declaration within a namespace is exported, the enclosing namespace (excluding members that aren't explicitly exported in that namespace) is also implicitly exported. If a namespace is explicitly exported, all declarations within that namespace definition are exported.
133
135
134
136
When the compiler does argument-dependent lookup for overload resolutions in the importing translation unit, it considers functions declared in the same translation unit (including module interfaces) as where the type of the function's arguments are defined.
135
137
136
138
### Module partitions
137
139
138
-
A module partition is similar to a module, except it shares ownership of all declarations in the entire module. All names exported by partition interface files are imported and re-exported by the primary interface file. A partition's name must begin with the module name followed by a colon. Declarations in any of the partitions are visible within the entire module. No special precautions are needed to avoid one-definition-rule (ODR) errors. You can declare a name (function, class, and so on) in one partition and define it in another. A partition implementation file begins like this:
140
+
A module partition is similar to a module, except:
141
+
- It shares ownership of all declarations in the entire module.
142
+
- All names exported by partition interface files are imported and exported by the primary interface file.
143
+
- A partition's name must begin with the module name followed by a colon (`:`).
144
+
- Declarations in any of the partitions are visible within the entire module.\
145
+
- No special precautions are needed to avoid one-definition-rule (ODR) errors. You can declare a name (function, class, and so on) in one partition and define it in another.
146
+
147
+
A partition implementation file begins like this, and is an internal partition from a C++ standards perspective:
139
148
140
149
```cpp
141
150
module Example:part1;
142
151
```
143
152
144
-
The partition interface file begins like this:
153
+
A partition interface file begins like this:
145
154
146
155
```cpp
147
156
exportmodule Example:part1;
148
157
```
149
158
150
-
To access declarations in another partition, a partition must import it, but it can only use the partition name, not the module name:
159
+
To access declarations in another partition, a partition must import it. But it can only use the partition name, not the module name:
151
160
152
161
```cpp
153
162
module Example:part2;
154
163
import :part1;
155
164
```
156
165
157
-
The primary interface unit must import and re-export all of the module's interface partition files like this:
166
+
The primary interface unit must import and re-export all of the module's interface partition files, like this:
158
167
159
168
```cpp
160
169
exportimport :part1;
161
170
exportimport :part2;
162
-
...
163
171
```
164
172
165
173
The primary interface unit can import partition implementation files, but can't export them. Those files aren't allowed to export any names. This restriction enables a module to keep implementation details internal to the module.
166
174
167
175
## Modules and header files
168
176
169
-
You can include header files in a module source file by putting the`#include` directive before the module declaration. These files are considered to be in the *global module fragment*. A module can only see the names in the global module fragment that are in headers it explicitly includes. The global module fragment only contains symbols that are used.
177
+
You can include header files in a module source file by putting an`#include` directive before the module declaration. These files are considered to be in the *global module fragment*. A module can only see the names in the global module fragment that are in the headers that it explicitly includes. The global module fragment only contains symbols that are used.
Copy file name to clipboardExpand all lines: docs/cpp/tutorial-named-modules-cpp.md
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -92,19 +92,19 @@ This line identifies this file as the primary module interface and gives the mod
92
92
93
93
This name is also where the "named" in "named module" comes from. The files that are part of this module use this name to identify themselves as part of the named module. A named module is the collection of module units with the same module name.
94
94
95
-
We should talk about the API we'll implement for a moment before going further. It impacts the choices we make next. The API represents different shapes. We're only going to provide a couple shapes in this example: `Point` and `Rectangle`. `Point` is meant to be used as part of more complex shapes, such as `Rectangle`.
95
+
We should talk about the API we'll implement for a moment before going further. It impacts the choices we make next. The API represents different shapes. We're only going to provide a couple shapes in this example: `Point` and `Rectangle`. `Point` is meant to be used as part of more complex shapes such as `Rectangle`.
96
96
97
97
To illustrate some features of modules, we'll factor this API into pieces. One piece will be the `Point` API. The other part will be `Rectangle`. Imagine that this API will grow into something more complex. The division is useful for separating concerns or easing code maintenance.
98
98
99
-
So far, we've created the primary module interface that will expose this API. Let's now build the `Point` API. We want it to be part of this module. For reasons of logical organization, and potential build efficiency, we want to make this part of the API easily understandable on its own. To do so, we'll create a *module partition* file.
99
+
So far, we've created the primary module interface that will expose this API. Let's now build the `Point` API. We want it to be part of this module. For reasons of logical organization, and potential build efficiency, we want to make the code for this part of the API a *module partition* file.
100
100
101
-
A module partition file is a piece, or component, of a module. What makes it unique is that it can be treated as an individual piece of the module, but only within the module. Module partitions can't be consumed outside of a module. Module partitions are useful for dividing the module implementation into manageable pieces.
101
+
Module partitions are useful for dividing the module implementation into manageable pieces. A module partition file is a piece, or component, of a module. What makes it unique is that it can be treated as an individual piece of the module--but only within the module. Module partitions can't be consumed outside of a module.
102
102
103
103
When you import a partition into the primary module, all its declarations become visible to the primary module regardless of whether they're exported. Partitions can be imported into any partition interface, primary module interface, or module unit that belongs to the named module.
104
104
105
105
## Create a module partition file
106
106
107
-
### `Point` module partition
107
+
### `Point` module partition example
108
108
109
109
To create a module partition file, in the **Solution Explorer** right-click **Source Files**, then select **Add** > **Module**. Name the file *`BasicPlane.Figures-Point.ixx`* and choose **Add**.
110
110
@@ -123,11 +123,11 @@ export struct Point
123
123
124
124
The file starts with `export module`. These keywords are also how the primary module interface begins. What makes this file different is the colon (`:`) following the module name, followed by the partition name. This naming convention identifies the file as a *module partition*. Because it defines the module interface for a partition, it isn't considered the primary module interface.
125
125
126
-
The name `BasicPlane.Figures:Point` identifies this partition as part of the module `BasicPlane.Figures`. (Remember, the period in the name has no special meaning to the compiler). The colon indicates that this file contains a module partition named `Point` that belongs to the module `BasicPlane.Figures`. We can import this partition into other files that are part of this named module.
126
+
The name `BasicPlane.Figures:Point` identifies this partition as part of the module `BasicPlane.Figures` (remember, the period in the name has no special meaning to the compiler). The colon indicates that this file contains a module partition named `Point` that belongs to the module `BasicPlane.Figures`. We can import this partition into other files that are part of this named module.
127
127
128
128
In this file, the `export` keyword makes `struct Point` visible to consumers.
129
129
130
-
### `Rectangle` module partition
130
+
### `Rectangle` module partition example
131
131
132
132
The next partition we'll define is `Rectangle`. Create another module file using the same steps as before: In **Solution Explorer**, right-click on **Source Files**, then select **Add** > **Module**. Name the file *`BasicPlane.Figures-Rectangle.ixx`* and select **Add**.
0 commit comments