0

の単一パラメーターコンストラクターがデフォルトで構築可能な型であるstd::list<T>必要があるのはなぜですか? Tつまり、次のコードはコンパイルされません。

struct Foo { // does not have default constructor.
  Foo (int i) {} 
}
int main(void) {
  std::list<Foo> l(10);
}

リストクラスの簿記が増えますが、 std::vector で既に行われているように、コンストラクトと破棄のイディオムを使用することは可能であるようです。

関連するメモとして、容量関数をリストに入れてみませんか? このような関数はメモリ割り当てコストを前払いし、後で異議​​を唱えるとオーバーヘッドを排除すると主張できpush_backます。少なくとも、2 つの STL シーケンス コンテナーのインターフェイスの一貫性が少し向上します。

4

6 に答える 6

5

std::list には意味がないため、容量関数はありません。ベクトルのようにサイズを変更する必要はありません。その容量は、使用可能なメモリによってのみ制限されますが、これは簡単には決定できません。

あなたが求めたことから、実際には reserve() が必要だと思います。これは vector にとっては 1 回限りです。すべての STL コンテナーですべての関数を一貫させる必要は特にありません。特に、他の関数にとってほとんど意味がない場合はそうです。

カスタム アロケータを使用して同じ効果を実現できます。マヌエルが提案したように、ブーストを見てください。

于 2009-03-29T21:26:10.030 に答える
4

型がデフォルトで構築可能であるという一般的な要件はありません。コピー可能で代入可能でなければなりません。10 個のアイテムのリストを作成しようとするため、コードは機能しません。それらは何らかの方法で構築する必要があるため、デフォルトのコンストラクターを使用する必要がありますが、この特定の場合に限られます。空のリストを作成して追加した場合、そのような要件はありません。

同じことが他のコンテナーにも当てはまります。以下をコンパイルしてみてください。

#include <vector>

struct A {
    A( int x ) : z(x) {}
    int z;
};

std::vector <A> a(10);

質問の 2 番目の部分に関しては、インターフェイスの一貫性が標準コンテナーの主要な設計基準ではなかったことを確認したいと思います。たとえば、あるタイプのコンテナーが「ドロップイン」の代替品であるという意図はありません。別。これについては、Scott Meyers の著書「Effective STL」の項目 1 と項目 2 で適切に説明されています。

于 2009-03-29T21:04:01.240 に答える
3

ニールはすでに主要な質問に答えています。

resize() を呼び出すときは、デフォルトのコンストラクターが必要なことにも注意してください。

オブジェクトへのポインターの STL リストを使用することでこれを回避できますが、これはすでに明らかだと思います。

関連するメモとして、容量関数をリストに入れてみませんか? このような関数は、メモリ割り当てコストを前払いし、後でオブジェクトを push_back するときにオーバーヘッドを排除すると主張できます。少なくとも、2 つの STL シーケンス コンテナーのインターフェイスの一貫性が少し向上します。

ここでの問題は、 STL リストがクロスリスト スプライシングを許可していることだと思います。前もってメモリを割り当てたい場合は、Boost Pool Allocatorを参照してください。

于 2009-03-29T21:14:41.120 に答える
2

その理由は、n 個の要素 (n はコンストラクターで使用したパラメーター) のリストを作成すると、リストは n 個の要素の構造を T() のコピーで埋めるためです。

list については、sgi stl のドキュメントを参照してください。

于 2009-03-29T21:14:06.253 に答える
1

それで、あなたの質問は本当に「なぜリストに予備と容量の機能がないのですか?」です。

その答えは、リスト用に事前にメモリを予約する理由がないということです。新しい要素を追加するために既存の要素の再割り当てとコピーが必要になることはなく、リストの内容を保持するメモリが連続している必要はなく、イテレータは必要ありません。を実行すると無効になりlist::push_back()ます。

これらすべてがの存在の理由であり、vector<>::reserve()新しい要素のためにメモリを予約することは、が生のメモリへのvector<>配置を実行する理由です。new

于 2009-03-29T21:58:29.393 に答える
0

std::list の単一パラメーター コンストラクターで T がデフォルトで構築可能な型である必要があるのはなぜですか?

このコンストラクターは、要素 (パラメーターとして渡す数値) を含むリストを作成するためです。各要素の値はデフォルトになります。また、2 番目の要素値で初期化される要素を持つリストを作成するために、2 つのパラメーターを持つコンストラクターを使用することもできます。

関連するメモとして、容量関数をリストに入れてみませんか?

リストに新しい要素を追加するコストは、ベクトルの場合よりもはるかに少ないため、意味がありません。

std::vector にはそのような制限はありません。私の質問は、std::list でも同じ手法 (イディオムの作成/破棄) を使用しないのはなぜですか?

制限ではありません。そのようなコンストラクターを使用しない場合、デフォルトの初期化子は必要ないためです。ベクトルについても同じことが言えます。

于 2009-03-29T21:07:53.430 に答える