質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

Q&A

解決済

2回答

1709閲覧

C++のdirectory_iteratorについての質問

shin_kano_

総合スコア1

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

0グッド

1クリップ

投稿2022/03/30 12:22

C++のファイルを扱うdirectory_iteratorクラスについて質問させていただきます。
(私の環境は、windowsにMinGW(minimalist gnu for windows)をインストールしています)
C++ 日本語referenceによると、サンプルコードは
https://cpprefjp.github.io/reference/filesystem/directory_iterator.html

lang

1#include <iostream> 2#include <filesystem> 3#include <fstream> 4 5namespace fs = std::filesystem; 6 7int main() 8{ 9 fs::create_directory("dir_a"); 10 std::ofstream{"dir_a/a.txt"}; 11 12 fs::create_directory("dir_a/dir_b"); 13 std::ofstream{"dir_a/dir_b/b.txt"}; 14 15 // dir_aディレクトリ直下に含まれる全ファイルを出力 16 for (const fs::directory_entry& x : fs::directory_iterator("dir_a")) { 17 std::cout << x.path() << std::endl; 18 } 19}

のあり、私の環境で正常に動作しました。

  1. この中の、

directory_iterator("dir_a")
は、どのようにコンストラクタがよばれているのか(headerファイルのどのコンストラクタに当たるのか)教えていただけると幸いです。
2. あと、範囲for文は

lang

1{ 2 auto && __range = for-range-initializer; 3 for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) { 4 for-range-declaration = *__begin; 5 statement 6 } 7}

といった風に展開される(https://cpprefjp.github.io/lang/cpp11/range_based_for.html)とのことですが、headerファイルからはメンバ関数(begin,end)を見つけることができなかったので、その点についてもどうなっているのか教えていただきたいです。

初心者なので、的外れな質問かもしれませんが、どうか回答よろしくお願いします

mingwでdirecory_iteratorが定義されているヘッダファイル
(lib\gcc\mingw32\9.2.0\include\c++\bits\fs_dir.h,一部改行を削除)

lang

1class directory_iterator{ 2 public: 3 typedef directory_entry value_type; 4 typedef ptrdiff_t difference_type; 5 typedef const directory_entry* pointer; 6 typedef const directory_entry& reference; 7 typedef input_iterator_tag iterator_category; 8 directory_iterator() = default; 9 explicit 10 directory_iterator(const path& __p) 11 : directory_iterator(__p, directory_options::none, nullptr) { } 12 directory_iterator(const path& __p, directory_options __options) 13 : directory_iterator(__p, __options, nullptr) { } 14 directory_iterator(const path& __p, error_code& __ec) 15 : directory_iterator(__p, directory_options::none, __ec) { } 16 directory_iterator(const path& __p, directory_options __options, 17 error_code& __ec) 18 : directory_iterator(__p, __options, &__ec) { } 19 directory_iterator(const directory_iterator& __rhs) = default; 20 directory_iterator(directory_iterator&& __rhs) noexcept = default; 21 ~directory_iterator() = default; 22 directory_iterator& 23 operator=(const directory_iterator& __rhs) = default; 24 directory_iterator& 25 operator=(directory_iterator&& __rhs) noexcept = default; 26 const directory_entry& operator*() const noexcept; 27 const directory_entry* operator->() const noexcept { return &**this; } 28 directory_iterator& operator++(); 29 directory_iterator& increment(error_code& __ec); 30 __directory_iterator_proxy operator++(int) 31 { 32 __directory_iterator_proxy __pr{**this}; 33 ++*this; 34 return __pr; 35 } 36 private: 37 directory_iterator(const path&, directory_options, error_code*); 38 friend bool 39 operator==(const directory_iterator& __lhs, 40 const directory_iterator& __rhs) noexcept 41 { 42 return !__rhs._M_dir.owner_before(__lhs._M_dir) 43 && !__lhs._M_dir.owner_before(__rhs._M_dir); 44 } 45 friend bool 46 operator!=(const directory_iterator& __lhs, 47 const directory_iterator& __rhs) noexcept 48 { return !(__lhs == __rhs); } 49 friend class recursive_directory_iterator; 50 std::__shared_ptr<_Dir> _M_dir; 51 };

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

この中の、directory_iterator("dir_a") は、どのようにコンストラクタがよばれているのか

explicit directory_iterator(const path& p);
コレが動いてますね。string から path への暗黙変換が行われ、上記コンストラクタに渡されています。

  2. あと、範囲for文は...

あなた読むとこ間違ってます。メンバ begin, end を持たないときはコッチ↓

C++

1{ 2 auto && __range = for-range-initializer; 3 4 for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) { 5 for-range-declaration = *__begin; 6 7 statement 8 } 9}

投稿2022/03/30 13:50

編集2022/03/30 15:56
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shin_kano_

2022/03/30 23:50

回答ありがとうございます。 まだ少し疑問が残っているで質問させていただきます。 1. についてなのですが、explicitは暗黙の型変換を禁止するとあったのですが、stringからpathの返還は行われるのでしょうか? 2. おっしゃられたbegin()についてなのですが ```lang-c++ inline directory_iterator begin(directory_iterator __iter) noexcept { return __iter; } ``` となっていて、戻り値がdirectory_iteratorになっていて、directory_entryではないので、うまくいかない気がするのですが、その点についても教えてください
episteme

2022/03/31 07:44

> stringからpathの返還は行われるのでしょうか? pathのコンストラクタ、調べてみましたか? > directory_entryではないので、うまくいかない気がするのですが なぜうまくいかない?
shin_kano_

2022/03/31 11:10

> pathのコンストラクタにstringを引数を持つものがあるのは調べていたのですが、それが暗黙の型変換に あたらないのかと思いまして。。。違うみたいでした、すみません。 >本質問で書いた通り for (const fs::directory_entry& x : fs::directory_iterator("dir_a")) { std::cout << x.path() << std::endl; } と書いてうまくいっているので、auto __beginのautoはdirectory_entryなのかなと思ったのですが どうでしょうか
episteme

2022/03/31 13:18

> auto __beginのautoはdirectory_entryなのかなと思ったのですが なんで? __begin が directory_entry だったら ++__begin も *__begin もできんやんか
shin_kano_

2022/03/31 22:11

>そうっすね。 重ね重ね質問して恐縮なんすけど、じゃあどうして for (const fs::directory_entry& x : fs::directory_iterator("dir_a")) { std::cout << x.path() << std::endl; } が動くんすか?
shin_kano_

2022/04/02 02:58

ありがとうございました、すっきり解決しました。
guest

0

C++

1 for (const fs::directory_entry& x : fs::directory_iterator("dir_a")) { 2 std::cout << x.path() << std::endl; 3 }

範囲for文を展開すると、

C++

1 { 2 fs::directory_iterator di = fs::directory_iterator("dir_a"); 3 for (fs::directory_iterator b = begin(di), e = end(di); b != e; ++b) { 4 const fs::directory_entry& x = *b; 5 std::cout << x.path() << std::endl; 6 } 7 }

directory_iterator の begin と end を展開すると、

C++

1 for (fs::directory_iterator b = fs::directory_iterator("dir_a"), 2 e = fs::directory_iterator(); b != e; ++b) { 3 const fs::directory_entry& x = *b; 4 std::cout << x.path() << std::endl; 5 }

投稿2022/03/31 14:53

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問