ディレクトリの再帰的な扱い
最後に、冒頭のサンプルで紹介したdirectory_iterator/recursive_directory_iterator:両者はディレクトリを示すpathを引数にコンストラクトします。ディレクトリ内の列挙にはdirectory_iterator、列挙中にディレクトリを見つけたとき、その中に入って再帰的に列挙したいならrecursive_directory_iteratorを使います。directory_iteratorはdirectory_entryを指し、さらにdirectory_entryはpathに暗黙変換できるので、以下のコードでカレント・ディレクトリ内を列挙できます。
directory_iterator first = current_path(); // 再帰的に列挙するなら
directory_iterator last; // recursive_directory_iterator
while ( first != last ) {
path p = *first;
...
++first;
}
加えてdirectory_iterator/recursive_directory_iteratorを引数にとるヘルパ関数begin()/end()が定義されていて、begin()は引数に与えられた(recursive_)directory_iteratorをそのまま返し、end()は空の(つまり列挙の終端を示す)(recursive_)directory_iteratorを返します。C++11で導入されたrange-based for構文:for ( 〇 : △ ) □は、
{
auto&& __range = △;
auto __begin = __range.begin() または begin(__range);
auto __end = __range.end() または end(__range);
for ( ; __begin != __end; ++begin ) {
〇 = *__begin;
□
}
と解釈されます。つまりdirectory_iteratorを引数とするbegin()とend()が定義されているおかげでディレクトリ内の列挙コードは
for ( auto entry : directory_iterator(current_path()) ) {
path p = entry;
...
}
と書ける、というのが冒頭サンプルのタネ明かし。
なかなかに使い勝手が良さそうなfilesystemです。アプリケーションでは扱う頻度のかなり高いディレクトリ/ファイル操作は従来OSごとに異なるAPIで実装していたのが、filesystemのおかげでコード一本書けばLinuxでもWindowsでも動いてくれるのは有難いです。C++以降、threadなどのよく使われるけどOS依存な機能が少しずつ標準ライブラリに仲間入りしています。2020年のC++(になるはずの):C++1zにはnetworkまわりが標準に入るらしいですよ。
