以下が機能しないのはなぜですか。
#include <iostream>
#include <fstream>
#include <stack>
std::stack<std::ifstream> s;
-PT
std::stack
(すべてのSTLコンテナーと同様に)、含まれているタイプが「割り当て可能」である必要があります。STLで言えば、これは、コピーコンストラクターと。が必要であることを意味しますoperator=
。std::ifstream
これらのどちらも持っていません。
I/Oストリームをコピーして割り当てることができない理由を想像できます。同じストリームのコピーが2つある場合に何が起こるかについてのセマンティクスは、明らかではありません。一方のコピーからの読み取りまたは一方のコピーへの書き込みは、もう一方のコピーの位置に影響を与える必要がありますか?一方のストリームを閉じると、もう一方のストリームを閉じる必要がありますか?等
「sのコンテナstd::ifstream
」が必要な場合、実際に作成する必要があるのは「std::ifstream*
sのコンテナ」です。非定数ポインタは常に割り当て可能です。注意点は、この場合、もちろん、コンテナはあなたのためにそれをしないので、コンテナを破壊する前にあなた自身がポインタを削除することを確認しなければならないということです。
ストリームはコピーできないため、技術的に標準のコンテナに入れることができます。
ただし、ストリームへのポインタを格納することで、これを回避できます。ただし、ストリームへのポインタを(特に動的に割り当てられている場合は)標準のコンテナに格納する必要はありません。ですから、私たちは解決策を後押しすることを目指しています。
Boostにはポインタコンテナの概念があります。
これにより、オブジェクトを動的に割り当て、ポインタをポインタコンテナに格納できます。ポインタコンテナは、オブジェクトの所有権を取得し、(ポインタではなく)オブジェクトであるかのように動的オブジェクトにアクセスできるようにします。
ポインタコンテナが所有権を取得するため、オブジェクトの削除について心配する必要はありません。コンテナはそれを行います。
含まれているオブジェクトへのアクセスをポインターではなくオブジェクトとして提供するため、より自然なファション(ポインターのコンテナーでキャンプ)で標準アルゴリズムのストリームを使用できます。
ここでタイラーをバックアップします(+1に投票した後)。
stlコンテナは、指定したオブジェクトの場所全体にコピーを作成します。必要に応じて、慎重に作成されたコピーコンストラクターと参照カウントなどを備えたデストラクターを備えた特別なオブジェクトを提供することで、これに対処できます。
一般的に、私はその方法があまりにも面倒だと思います。経験則として、コンテナ内の小さなオブジェクトのみを使用してください。構造体またはクラスのスタックを作成する場合は、代わりにそれらへのポインターを使用してください。