17

Tどのタイプでも、タイプstd::list<T>は同じ一定のサイズになると想定できますか?明確にするために、私は「メイン」タイプ自体のサイズのみを意味し、それによって割り当てられたメモリのサイズは意味しません。

Tそれ自体のサイズは、アロケータを使用して割り当てられたリストノードのサイズにのみ影響するはずだと考えるのは理にかなっているようです。

sizeof(std::list<T>)ただし、私が考えることができる変動を引き起こす可能性のある2つのことがあります。

  1. std::list一部のTインスタンスをstd::list<T>それ自体に配置することにより、型を「最適化」しようとする標準C++ライブラリ。それは私には悪い考えのように思えます、そしてそれはおそらく標準によって置かれた「一定時間」の要件を破ります。
  2. std::list<T>いくつかのタイプのライブラリスペシャライゼーションを持ち、スペシャライゼーションのサイズが異なる標準C++ 。

(1)や(2)の使い方は考えられませんが、間違っているかもしれません。

私が達成しようと考えているのは、std::list<T>insideを使用するテンプレートクラスに固定サイズのスライスアロケータを使用することです。


注:これは、さまざまなタイプの分散に関するものであり、さまざまなアロケータの分散に関するものでTはありません。私はすべてのインスタンス化を明示的に制御し、それらはすべてを使用しstd::allocatorます。

4

3 に答える 3

8

はい、できます。

list<T>私の知る限り、この規格はオブジェクトのサイズを正確に保証するものではありません。それでも、他の保証があります。


いくつかのことをデバンキングしましょう:

std::list一部のTインスタンスをstd::list<T>それ自体に配置することにより、型を「最適化」しようとする標準C++ライブラリ。それは私には悪い考えのように思えます、そしてそれはおそらく標準によって置かれた「一定時間」の要件を破ります。

O(5)はO(1)であるため、この数が制限されている限り、「一定時間」の要件に違反することはありません。ただし、操作中、ノードはメモリ内を移動せずに、spliceあるリストから別のリストに移動する必要があります。したがって、ローカルストレージは禁止されています。

std::list<T>いくつかのタイプのライブラリスペシャライゼーションを持ち、スペシャライゼーションのサイズが異なる標準C++ 。

std::list<T>ローカルストレージの可能性をすでに除外しているため、基本タイプの他のバリエーションを単独で想像することは困難です。


そして、重要なことについて心配しましょう。

aによって割り当てられるメモリstd::list<T>は、2番目のテンプレート引数であるアロケータによって提供されます。ほとんどのアロケータ(std::allocator<T>デフォルトを含む)は単純なポインタタイプを使用します:T*...ただし、アロケータはこのタイプを自由に変更する必要があります。

したがって、allocatorパラメーター(より正確にはそのポインター・タイプ)を変更することにより、std::list私が見たすべての実装でコンテナーのサイズを自然に変更します。

アロケータ自体が一部のタイプに特化している可能性があることに注意してください。ただし、再バインドの魔法を使用すると、達成するのが少し難しくなります。

于 2012-08-03T11:21:22.860 に答える
4

C ++ 11標準(コンテナ)の第23章では、サイズについて何も述べられていないため、技術的には、サイズが一定であると想定することはできません。実装者は、(理論的には)特定のプリミティブのフットプリントに影響を与える方法でコンテナを特殊化することができます。

実際には、静的アサーションをsizeof(list<T>) == sizeof(list<int>)使用sizeof(list<int>)して、「固定」サイズとして使用できます。発生する可能性のある最悪の事態は、コンパイル時のエラーです。

于 2012-08-03T11:19:14.060 に答える
0

クラスを使用std::list<T>するための固定サイズのスライスアロケータは、リスト自体にも固定サイズのスライスアロケータを使用しない限り、ほとんど意味がありません。おそらく、リストヘッダーよりもリストアイテムに多くの割り当てがあります。

これで、2番目のテンプレート引数であるアロケータを使用して、リストに独自の固定サイズのスライスアロケータを確実に提供できます。ただし、ひねりがあります。スライスの大きさがわかりません。Alist<T>はを受け入れますallocator<T>が、実際に必要なのはallocator<U>、Uがprev / nextポインターとTを含む構造体である場合です。これを取得するにはrebind、署名を持つメソッドを呼び出しますtemplate <typename T> template <typename T> allocator<U> allocator<T>::rebind<U>()

私は実際に一度それを行う必要があったので、私がしたことは、いくつかのスライスサイズのアロケータのコレクションを保持するオブジェクトを作成することでした。アロケータ自体は、これへの共有ポインタと、その引数のサイズのためのアロケータへの共有ポインタを保持していました。そして、再バインド時に、コレクションから適切なアロケータをプルするか、存在しない場合はアロケータを作成しました。これを行うと、副作用としてリストの割り当てが解決されます。これは、サイズが複数ある場合は、それぞれに個別のプールが作成されるためです。また、オブジェクトが大きくならないため、さまざまなサイズが存在するわけではありません。

于 2012-08-03T11:33:53.493 に答える