ステートメントは gcc に当てはまります
ここでのこのステートメントは正しくないようです: […]
標準や Visual Studio についてはわかりませんが、使用している C++ については知っています。これは GCC のものです。そこで、関連するヘッダーを確認できます。
oistream::open
次のようになります。
inline void
istream::open(const char* __s, ios_base::openmode __mode = ios_base::in) {
if (!_M_filebuf.open(__s, __mode | ios_base::in))
したがって、ここには 2 つのものがあります。メソッドを呼び出すときに指定しなかった場合のデフォルトの関数引数と、提供されたモードに常に or-ed される強制フラグです。したがって、どのモードを指定しても、入力モードは常に仕様に追加されます。他のコード、特にコンストラクターはこれに委譲します。と同様の状況が発生しofstream::open
ます。一方、デフォルトの引数fstream::open
がありますが、強制された引数はありません:
inline void
fstream::open(const char* __s,
ios_base::openmode __mode = ios_base::in | ios_base::out) {
if (!_M_filebuf.open(__s, __mode))
結果として、モードを渡さなくても問題ありません (少なくともこの実装では、詳細については @kmote の回答をお読みください)。ただし、モードを渡す場合は、いずれかまたは両方を渡す必要があります。指定した (または指定しなかった) モードに強制モードが追加されることはないためです。in
out
これは私が Apache のドキュメントを読む方法であり、少なくとも私の実装では、ソースは私の見解をサポートしています。これらはすべてテンプレート化されたコードであるため、別のコンパイラのヘッダーを調べて、これらの状況をどのように処理するかを確認できます。VSヘッダーを見て、basic_fstream
そのメソッドがどのように実装されているかを探して確認してください。
コンパイラ エラーの欠如
そうしないと、このコードはコンパイルされません。
コードは出力専用の双方向ストリームを開き、そこから入力を試みます。これがコンパイルに失敗する理由はありません。ストリームの静的タイプはfstream
、つまり双方向です。実行時にのみ、特定の意味を持つ特定のフラグをコンストラクターに渡します。コンパイラは(通常)それをチェックしないため、実際にストリームからの読み取りに失敗すると、コードは実行時に誤動作します。
Windows が実際に出力専用のファイルを開くことをサポートしているかどうかはわかりません。OS でサポートされているファイル モードは、読み取り専用と読み書きのみである可能性があります。out
(ここでは推測しているだけであることに注意してください。)その場合、出力のみのためにファイルを開き、後でそれから読み取ることは、実行時でも問題にはなりませんin|out
。書き込み専用ファイルをサポートするカーネルが存在するため、移植性のために正しいモードを選択する必要があります。