A

Module std

That is a big thing with an invention: You have to have a whole system that works.

– J. Presper Eckert

A.1 Introduction

At the time of writing, module std [Stroustrup,2021b] is unfortunately not yet part of the standard. I have reasonable hope it will be part of C++23. This appendix offers some ideas of how to manage for now.

The idea of module std is to make all the components of the standard library simply and cheaply available by a single import std; statement. I have relied on that throughout the chapters. The headers are mentioned and named mostly because they are traditional and universally available, and partly because they reflect the (imperfect) historical organization of the standard library.

A few standard-library components dump names, such as sqrt() from <cmath>, into the global namespace. Module std doesn’t do that, but when we need to get such global names we can import std.compat. The only really good reason for importing std.compat rather than std is to avoid messing with old code bases while still gaining some of the benefits from the increase in compile speeds from modules.

Note that modules, most deliberately, don’t export macros. If you need macros, use #include. Modules and header files coexist; that is, if you both #include and import an identical set of declarations, you will get a consistent program. This is essential for the evolution of large code bases from relying on header files to using modules.

A.2 Use What Your Implementation Offers

With a bit of luck, an implementation we want to use already has a module std. In that case, our first choice should be to use it. It may be labeled “experimental” and to use it may require a bit of setup or a few compiler options. So, first of all, explore if the implementation has a module std or equivalent. For example, currently (Spring 2022) Visual Studio offers a number of “experimental” modules, so using that implementation, we can define module std like this:

Image
export module std;
export import std.regex;            // <regex>
export import std.filesystem;    // <filesystem>
export import std.memory;       // <memory>
export import std.threading;     // <atomic>, <condition_variable>, <future>, <mutex>,
                                                     // <shared_mutex>, <thread>
export import std.core;             // all the rest

For that to work, we obviously have to use a C++20 compiler, and also set options to gain access to the experimental modules. Beware that everything “experimental” will change over time.

A.3 Use Headers

If an implementation doesn’t yet support modules or doesn’t yet offer a module std or equivalent, we can fall back to using traditional headers. They are standard and universally available. The snag is that to get an example to work, we need to figure out which headers are needed and #include them. Chapter 9 can help here, and we can look up the name of a feature we want to use on [Cppreference] to see which header it is part of. If that gets tedious, we can gather frequently used headers into a std.h header:

// std.h

#include <iostream>
#include<string>
#include<vector>
#include<list>
#include<memory>
#include<algorithms>
// ...

and then

#include "std.h"

The problem here is that #includeing so much can give very slow compiles [Stroustrup,2021b].

A.4 Make Your Own module std

This is the least attractive alternative because it’s likely to be the most work, but once someone has done it, it can be shared:

module;
#include <iostream>
#include<string>
#include<vector>
#include<list>
#include<memory>
#include<algorithms>
// ...

export module std;
export istream;
export ostream;
export iostream;
// ...

There is a shortcut:

export module std;

export import "iostream";
export import "string";
export import "vector";
export import "list";
export import "memory";
export import "algorithms";
// ...

The construct

import "iostream";

Importing a header unit is a half-way house between modules and header files. It takes a header file and makes it into something like a module, but it can also inject names into the global name-space (like #include) and it leaks macros.

This is not quite as slow to compile as #includes but not as fast as a properly constructed named module.

A.5 Advice

[1] Prefer modules provided by an implementation; §A.2.

[2] Use modules; §A.3.

[3] Prefer named modules over header units; §A.4.

[4] To use the macros and global names from the C standard, import std.compat; §A.1.

[5] Avoid macros; §A.1. [CG: ES.30] [CG: ES.31].

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.27.93