c++20 の module について


※初投稿且つ一夜漬けなので細かいところは許してください
#前置き
## 環境
- windows10
- visual studio 2022

## なぜなに
無名名前空間について苦悩していたんですが，c++にはモジュールという便利機能があることを発見したのです．
しかし，c++20であったのです．

## 問題
まずwindowsな点です（ひどい）
また，別にc++20である程度ならいいのですが，モジュールはコンパイル関係だけあって対応が難しかったんですね（とかいいながらclangもgccももう対応してくれている）

## 問題解決
ということでいろいろサイトを漁った結果，問題は全部解決しました．
clangもgccももう対応しているという話なのですが，今回はMicrosoftさんが力を入れてモジュールに対応してくれているという話なので，Visual Studio 2022を使っていきたいと思います．

#準備
まずVisual Studioを立ち上げます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/78219749-cfcc-43cc-b878-e154b00f9687.png)
次に「新しいプロジェクトの作成」を選択し，「空のプロジェクト」を作成します．
![2021-12-28 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/2ef065fd-e048-b197-744c-f0841b983b4d.png)
名前は適当にしてさくっと作成します．![2021-12-28 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/2c315ca4-e555-b82b-da66-ad66689e2b62.png)
作成したらとりあえず，ソリューションエクスプローラー（なかったら右上当たりの検索っぽいやつから検索してください）内のソリューションの一個下のプロジェクトを右クリックして，プロパティを選択します．![2021-12-28 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/0d06ed61-a01d-1804-6f43-3b79c7fa8876.png)

※構成，プラットフォームに気を付けてください
その後は構成プロパティ > C/C++ > 言語 > C++言語標準が「既定(ISO  C++14 標準)」になっていると思うので，
![2021-12-28 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/2661d746-740b-f75b-02ac-48b1f344c53c.png)
「ISO C++20 標準 (/std:c++20)」を選択します．
次にC++言語標準の下3個目（一番下）にある，「試験段階の C++ 標準ライブラリ モジュールを有効にする」をはいにします．
これであとは思う存分モジュールができます．

# コンパイル
ということで試してみましょう
まず，ソースファイルとヘッダーファイルとC++モジュールインターフェースユニット(.ixx)を
追加 > 新しい項目 から追加します．
![2021-12-28 (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890310/515288c4-8e0b-4078-8c7e-e65992192bae.png)

```c++:cpp
#include <iostream> // 古臭いコード
import <iostream>; // モダンなコード
```

因みにこれで#includeとかいう再インクルードしまくるゴミから解放されます．といっても現在ではまだ対応していませんが...．

##お試しコード

ということで適当にC++20の要素を詰めながらコードを書いてみました．Moduleの仕様に触れるように作ったんですが...途中で試してみたら，これが通らない！！原因はなんと不明です．具体的にはこれですね．linterさんは何の問題もないとおっしゃってるのに...．

```
1>C:\Users\nziq5\source\repos\c++20\Hello_C++20_Module\Hello_C++20_Module\Source.cpp(1,1): fatal error C1001: 内部コンパイラ エラーが発生しました。
1>(コンパイラ ファイル 'msc1.cpp'、行 1687)
1> この問題を回避するには、上記の場所付近のプログラムを単純化するか変更してください。
1>可能な場合、再現手順をこちらに入力してください: https://developercommunity.visualstudio.com
1>詳細については、Visual C++ ヘルプ メニューのサポート情報コマンドを
1>選択するか、サポート情報ヘルプ ファイルを参照してください
1>'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\bin\HostX86\x86\CL.exe' で内部コンパイラ エラーが発生しました。
1>    Visual C++ のサポート情報 コマンドを選択してください
1>    ヘルプ メニュー、またはサポート情報のヘルプ ファイルを参照してください
1>プロジェクト "Hello_C++20_Module.vcxproj" のビルドが終了しました -- 失敗。
```

無名名前空間の代わりにだとか，あくまでexportだけだとか言おうと思っていたんですが，そもそもダメでした...力尽きたので原因解明はこれを読んでる方に託しときます．
~~これでただの文法の思い違いだったら恥ずかしすぎる．例えばexportは全てに付けなければならないとか~~
###作ったコードの全貌
（下記をクリック）
<details><div>

```C++:Header.hpp
#include <iostream>
#include <string>

using std::u8string;

consteval unsigned nn(const unsigned i = 1, unsigned k = 1) {
	unsigned j = 1;
	for (unsigned n = 0; n < k; ++n) j *= i;
	return j;
}

const u8string str = u8"回目の「";
const unsigned i = nn (5, 7);

inline namespace header {
	using std::cout;
	using std::endl;
	using std::string;
	namespace impl {
		string str;
		static unsigned u = 0;
		bool is_utf8_multibyte_code_unit(char c) {
			return static_cast<unsigned char>(c) >= 0x80;
		}
	}
	export void PrintHello(string str = "Hello!", unsigned u = 0) {
		using namespace impl;
		cout << u
			 << reinterpret_cast<char>(::str.c_str()) // u8stringからchar8_t*からchar
			 << impl::str << reinterpret_cast<char>(u8"」📃")
			 << endl;
		impl::str = str;
		impl::u += u;
	}
}
```

```C++:Module.ixx
module;
#include "Header.hpp"

export module Module;

inline namespace module_ {
	 inline namespace header {
		 export void PrintHello(string, unsigned);
	 }
}
```

```C++:Source.cpp
import Module;

inline namespace tmp {
	int main () {
		// PrintHello (); 何故かエラー
		PrintHello ("Hello", 1);
	}
}
```

</div>
</summary>

とりま力尽きたのでここまで．
知りたいことがあったら参考全部載せるので自力か他力でどうぞ．

# 参考
## モジュール関連
[https://docs.microsoft.com/ja-jp/cpp/cpp/modules-cpp](https://docs.microsoft.com/ja-jp/cpp/cpp/modules-cpp "C++ のモジュールの概要")
[https://stackoverflow.com/questions/67393131/unable-to-import-c-modules](https://stackoverflow.com/questions/67393131/unable-to-import-c-modules "Unable to Import C++ Modules")
[https://logicalbeat.jp/blog/6223/](https://logicalbeat.jp/blog/6223/ "【C＋＋】C＋＋20のモジュールとincludeの違いについて詳しく調べてみた")
[https://mahori.jp/2021/04/05/cpp-std-u8string/](https://mahori.jp/2021/04/05/cpp-std-u8string/ "std::u8stringクラス")
[https://onihusube.hatenablog.com/entry/2021/05/28/214612](https://onihusube.hatenablog.com/entry/2021/05/28/214612 "[C++］C++20モジュールの変遷 - Module TSからC++20DISまで")
[https://cpprefjp.github.io/lang/cpp20/modules.html](https://cpprefjp.github.io/lang/cpp20/modules.html "C++日本語リファレンス")
[https://vector-of-bool.github.io/2019/03/31/modules-2.html](https://vector-of-bool.github.io/2019/03/31/modules-2.html "Understanding C++ Modules: Part 2: export, import, visible, and reachable")
[https://stackoverflow.com/questions/64877559/cant-use-iostream-as-module-in-c20-visual-studio](https://stackoverflow.com/questions/64877559/cant-use-iostream-as-module-in-c20-visual-studio "Can't use iostream as module in C++20 (Visual Studio)")

## (個人的に)モジュールの実行関連
[https://blog.imfing.com/2020/06/cpp-20-modules-hello-world/](https://blog.imfing.com/2020/06/cpp-20-modules-hello-world/ "C++ 20 Modules 尝鲜")
[https://itnext.io/c-20-modules-complete-guide-ae741ddbae3d](https://itnext.io/c-20-modules-complete-guide-ae741ddbae3d "C++20 Modules — Complete Guide
")
[https://devblogs.microsoft.com/cppblog/standard-c20-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/ "Standard C++20 Modules support with MSVC in Visual Studio 2019 version 16.8
")
[https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2016/april/visual-c-microsoft-pushes-c-into-the-future](https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2016/april/visual-c-microsoft-pushes-c-into-the-future "Visual C++ - C++ の将来に向けたマイクロソフトの後押し
")
[https://stackoverflow.com/questions/59447206/standard-way-of-importing-modules](https://stackoverflow.com/questions/59447206/standard-way-of-importing-modules "Standard way of importing modules")
[https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp](https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp "Overview of modules in C++")