それ import std で ー bits/stdc++.h 論争に決着！ C++ 標準ライブラリのモジュール化

# 要約

C++23以降では`import std;`と書けばすべての標準ライブラリが使えます。

# 言語機能としてのモジュール

C++20では、`#include`を置き換える新しいファイル分割の仕組みとしてモジュールが導入されました。

* [モジュール - cpprefjp](https://cpprefjp.github.io/lang/cpp20/modules.html)

モジュールは「ファイルの内容をその場に展開する」という原始的な仕組みの`#include`とは異なり、モジュール毎にコンパイルされます。
翻訳単位の肥大化が抑えられる事と、それぞれのモジュールが何度もコンパイルされることがない事から、コンパイル時間の短縮につながることが期待されています。

[MSVC 16.8でモジュールが完全サポートされる](https://devblogs.microsoft.com/cppblog/standard-c20-modules-support-with-msvc-in-visual-studio-2019-version-16-8/)(予定)など、実装も揃いつつあります。

ただし、言語機能としてのモジュールは導入されたものの、標準でモジュールとして提供されるライブラリはありません[^1]。

[^1]: 標準C++ライブラリにはヘッダーユニットという救済措置があります。

# 標準ライブラリのモジュール化

C++23では、ついに標準ライブラリがモジュール化されます。

* [P2465R3 Standard Library Modules std and std.compat](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2465r3.pdf)

## モジュール `std`

モジュール `std` は、C++標準ライブラリ全体を含むモジュールです。以下のようにインポートすると、すべての機能が使えるようになります。

```cpp
import std;
```

`std` はグローバル名前空間には何も導入しません。

## モジュール `std.compat`

モジュール `std.compat` は、モジュール `std` の内容に加えて、グローバル名前空間にもC言語互換ライブラリの内容を導入します。これは、古いコードをモジュールベースに書き換えるとき、互換性を保つために使用できます。

例えば、`std` をインポートした場合、 `printf` 関数は `std` 名前空間にのみ導入されます。`std.compat` をインポートすると、`std` 名前空間とグローバル名前空間の両方に導入されます。

## マクロ

`std`、`std.compat` のいずれも、マクロは含みません。

:::note info
C++20の仕様により、モジュールはマクロをエクスポートできません
:::

標準ライブラリで定義されるマクロを使いたい場合は、引き続きヘッダーファイルを `#include` するか、ヘッダーユニットとしてインポートする必要があります。

## 以前の提案

以前、以下のようなサブモジュールが提案されていました([P0581R1 Standard Library Modules](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0581r1.pdf))。

C++23では、最小限のサポートとして標準ライブラリ全体を含むモジュールだけが採用され、**これらのサブモジュールは採用されていません**。

* モジュール `std.fundamental`  
  `<cstddef>`、`<limits>`、`<cfloat>`、`<cstdint>`、`<new>`、`<typeinfo>`、`<exception>`、`<initializer_list>`、`<csignal>`、`<csetjump>`、`<cstdlib>`、`<stdexcept>`、`<system_error>`、`<utility>`、`<tuple>`、`<optional>`、`<variant>`、`<any>`、`<bitset>` (I/Oのフォーマット宣言を除く)、`<type_traits>`、`<ratio>`、`<chrono>`、`<ctime>`、`<atomic>`、`<typeindex>`、`<memory>`のうち`std::unique_ptr`と`std::shared_ptr`および関連するクラスと関数
* モジュール `std.core`  
    `std.fundamental`の再エクスポート、`<array>`、`<list>`、`<forward_list>`、`<vector>`、`<deque>`、`<queue>`、`<stack>`、`<map>`、`<set>`、`<unordered_map>`、`<unordered_set>`、`<iterator>`、`<algorithm>`、`<execution>`、`<functional>`、`<string_view>`、`<string>`(I/Oのフォーマット宣言を除く)、`<memory>`の`std.fundamental`に入らなかった部分、`<memory_resource>`、`<scoped_allocator>`、`<regex>`
* モジュール `std.io`  
    `<cctype>`、`<cwctype>`、`<cwchar>`、`<cstdlib>`、`<cuchar>`、`<locale>`、`<codecvt>`、`<clocale>`、`<iosfwd>`、`<iostream>`、`<ios>`、`<streambuf>`、`<istream>`、`<ostream>`、`<iomanip>`、`<sstream>`、`<fstream>`、`<cstdio>`、`<complex>`のI/Oフォーマット宣言、`<string>`のI/Oフォーマット宣言、`<bitset>`のI/Oフォーマット宣言
* モジュール `std.os`  
    `<filesystem>`
* モジュール `std.concurrency`  
    `<mutex>`、`<thread>`、`<condition_variable>`、`<shared_mutex>`、`<future>`
* モジュール `std.math`  
    `<complex>` (I/Oのフォーマット宣言を除く)、`<numeric>`、`<valarray>`、`<random>`、`<cmath>`

# `bits/stdc++.h` とは

特定の処理系で提供される、標準ライブラリをすべてインクルードしている便利なヘッダーです。移植性は皆無ですが競技ではよく使われています。

* [で、結局 #include \<bits/stdc++.h\> って何?](https://qiita.com/hakatashi/items/f9d9abf05a002b5c4dc5)

C++23以降では、`#include "bits/stdc++.h"`の代わりに`import std;`と書けます。これは標準ライブラリであり、ポータブルです😃

# 参考リンク

* [モジュール - cpprefjp](https://cpprefjp.github.io/lang/cpp20/modules.html)
* [C++23 以降に向けた提案 - cppmap](https://cppmap.github.io/standardization/cppx/)
* [ゲーム開発者のための C++11～C++20, 将来の C++ の展望](https://speakerdeck.com/cpp/cedec2020?slide=125)
* [Standard C++20 Modules support with MSVC in Visual Studio 2019 version 16.8](https://devblogs.microsoft.com/cppblog/standard-c20-modules-support-with-msvc-in-visual-studio-2019-version-16-8/)
* [P0581R1 Standard Library Modules](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0581r1.pdf)
* [P2465R3 Standard Library Modules std and std.compat](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2465r3.pdf)