実装するすべての STL コンテナresize
は、コピーのソースがデフォルトで構築されたオブジェクトであっても、コピーを使用して新しい要素を設定しますか?
なぜこのように行われるのですか?
利点はなく、いくらかのコストがかかります。
コンテキストとして、コピーできない要素のランダム アクセス コンテナーを探しているときに、これに出くわしました。
実装するすべての STL コンテナresize
は、コピーのソースがデフォルトで構築されたオブジェクトであっても、コピーを使用して新しい要素を設定しますか?
なぜこのように行われるのですか?
利点はなく、いくらかのコストがかかります。
コンテキストとして、コピーできない要素のランダム アクセス コンテナーを探しているときに、これに出くわしました。
複雑さを軽減します。確かにコピー構築のケースが必要であり、デフォルト構築は、デフォルトで構築されたオブジェクトを複製するものとしてモデル化できます。
パフォーマンスの低下は無視できます。ゼロの書き込みは、ゼロのコピーとほぼ同じ速度です。いずれにせよ、すべてのコンテナはコピー可能性を必要とするため、互換性のペナルティはゼロです。一方、デフォルト構築は必要ありません。
コピー不可能なオブジェクトを含む標準コンテナーを本当に使用したい場合は、C++0x と を使用したインプレース構築を調べてくださいemplace
。emplace
ただし、複数の要素を一度に処理する方法はありません。( を使用している場合は、ループdeque
に対してパフォーマンスが大幅に低下することはありません。)emplace
resize
あなたの場合、おそらく、これらのオブジェクトへのポインターをコンテナーに格納する方がよいでしょう。ポインターはコピーできます。
コンテナへのコピーについて 代替手段は何ですか?保存されているものを保存するためにメモリの新しいブロックを再割り当てする必要がある場合は、何らかの方法でそこに既存のデータを取得する必要があります!
この動作について私が考えることができる唯一の理由は、コンテナーが挿入をサポートしており、挿入にはコピーが必要であるということです。deque
デフォルトで新しい要素を構築する(ページ化され、連続していない)のと同様の方法でサイズ変更をサポートするコンテナを作成できるはずです。ただし、要素の挿入とともにコンテナー全体の割り当てを禁止する必要があります。代わりに、コレクションで構築されたオブジェクトを変更できます。
私の推測では、挿入をサポートせず、値型のコピーを実装しないコレクションの必要性を認識した人は誰もいなかったと思います。別のメモとして、おそらく、これを閉じる前に wiki としてタグ付けする必要があります ;)
標準コンテナは、値型に対する CopyConstructible および Assignable の要件を定義しており、これらの要件は、コンテナおよびシーケンスに対するすべての操作をサポートするのに十分です (連想コンテナと比較できるようにしたい場合もありますが、それは必須ではありません。代わりにコンパレータを提供します)。
あなたが求めているのは、コンテナの一部とシーケンスからの何かで構成される一連の操作に対する1つの要件セットを持つことです(つまりresize()
、コンテンツを決して再配置しないコンテナの1パラメータoperator[]
、clear()
およびを除くイテレータインタフェース*it = t
) 、残りの要件の別のセット。標準ライブラリは、これを逆に行うことを好みます。ほとんどすべてをカバーする共通の要件セットを選択し、機能の小さなビットに対して追加の要件を設定します ( resize()
2 番目を指定せずに呼び出すために、デフォルトで構成可能であるという要件など)。パラメータ)。
コンテナは、特定の一連の操作を念頭に置いて考案されたものではありません-コピーと割り当ては、それらが行うように設計されていること、つまり、コンテナに入れられる値を含めることに固有のものであるため、ステパノフの心の中ではそうではないと推測します「ちょっとした機能」。したがって、抽象コンテナは提案された ResizeableCollectionOfDefaultConstructedObjects よりも大きいため、より広い要件があります。実際、resize()
CollectionOfDefaultConstructedObjects はほとんど単なる配列です。STL と C++ 標準の設計者は、抽象化する価値があると考えるほど頻繁にユースケースに遭遇しなかったと思います。