CおよびC++アプリケーションに関する最新の傾向、および最新とは過去数年という意味で、std::allocator
sが実際よりも頻繁に使用されることを期待していました。
最近のアプリケーションは通常、マルチスレッド化されているか、並行処理の形式であり、特にゲームやマルチメディアアプリケーションなどの一部の分野では、大量のメモリを管理します。そのため、割り当て/割り当て解除の通常の高コストが発生し、古いアプリケーションよりもパフォーマンスに影響を与えます。
しかし、このようなstd::allocator
sによるメモリ管理は一般的ではないため、私が知っている1つのライブラリを数えることすらできません。つまり、標準化されたメモリ管理方法に関する根拠を使用しています。
std::allocator
が人気がない本当の理由はありますか?技術的な理由?
ここには2つの質問があります。
1)std::allocator
がさらに使用されないのはなぜですか?
短い答えは、ほとんどの用途ではnew
とdelete
を使用することで十分だからです。
最初に、C++ 11アロケーターの概念の目的の概要。基本的に、new Foo
を実行すると、メモリが割り当てられ、そのメモリ内にオブジェクトが構築されます。
しかし、メモリを割り当てて2つの別個のステップとして構成する必要がある場合はどうでしょう。この典型的な例はstd::vector
です。これは、メモリをすぐに初期化せずにメモリを割り当てることができますが、コンテナに追加するときに要素を構築します。 std::allocator
のポイントは、これらの個別のステップを統一された方法で実行するためのインターフェースを提供することです。
ただし、ほとんどのユーザーにとっては、そのレベルの制御は必要ありません。例外をクリーンアップするときに覚えておかなければならないことの1つに過ぎないためです。
2)なぜC++のAllocator
の概念を利用しないのですか?
ほとんどの場合、必要はありません。それらを使用する傾向がある唯一のクラスは、ユーザーが割り当てるメモリのソースをより詳細に制御できるようにするクラスです。標準ライブラリコンテナーは、ユーザーが選択した場合にユーザーがこれらの決定を行うことができるように記述されていますが、デフォルトでは通常のアロケーターを使用します。
言語またはライブラリの概念の人気は、その基礎となる複雑さと逆相関にあります。
_std::allocator
_は低レベルの概念であるため、潜在的な落とし穴があります。カスタムアロケーターを前もって持つことは、時期尚早の最適化と判断される可能性があります。さらに、他の低レベルの概念と同様に、独自の割り当ての複雑さを処理するオーバーヘッドが絶対的に正当化されない限り、ワーク割り当て管理をライブラリ(stdlib、boost)に委任することが一般的に推奨されます。
ポインターをこの論文のサポート例の1つと考えてください。私たちは、メモリへの束縛されないアクセスとオーバーヘッドなしのポインタを愛していますが、C++では、スコープ/ raiiラッパーを使用して複雑さを管理する方がよいことを知っています。明確に定義されたユースケース。
Std :: allocatorを使用するときは、ABIとAPIの互換性、およびコードが関与しているときの望ましい動作などの素晴らしい質問を考慮する必要がありますstd::vector<T,A1>().swap(std::vector<T,A2>())
は、異なる(そしてステートフルです!)_A1
_および_A2
_アロケーターを使用します。さらに、一部のコンテナーは、意図したとおりにアロケーターを使用しません!たとえば、_std::list<T,A>
_または_std::map<K,T,C,A>
_を見てください。当然のことながら、リストにT
タイプのオブジェクトを割り当てるためにアロケータが使用されるか、マップに_pair<const K,T>
_が割り当てられますが、実際には、標準ライブラリの実装ではリストまたはマップを割り当てるよう求められますノード、およびノードのサイズでさえ、リリースビルドとデバッグビルドで異なる場合があります。カスタムアロケーターは細部に満ちており、追加された複雑さと詳細は、最も一般的なプログラミングタスクには不要です。
アロケーターは、依存関係が注入されたポリシーであり、標準コンテナーに組み込まれます。クライアントコードがインスタンス化から割り当てポリシーを分離できるようにするためにほとんどありますすでに実装されているコンテナ。
Std ::コンテナを使用する必要があり、デフォルトの割り当てポリシー(std :: allocatorによって実装されている)がプロジェクトのニーズに適合しない場合に問題が発生します(たとえば、std :: vector実装でさらに多くの場合にスローしたい場合) 1024を超えるオブジェクトが割り当てられている場合、メモリプールを使用するか、割り当てがすべて特定のメモリ領域などに事前に割り当てられるようにします。
コンテナーに別のアロケーターを注入できなかった場合、一部のプロジェクトでstd :: containersを一緒に使用することが禁止されます。
これを回避するには(そして、複雑なメモリ要件がある場合でもstd ::コンテナーを引き続き使用できるようにするため)、アロケーターはコンテナーのテンプレートパラメーターです。
あなたの質問に答えるために:ほとんどの人はstd :: allocatorsを使用しません。クライアントコードを書くとき、割り当てを完全に制御できるからです。割り当てポリシーを挿入する必要がないため、いつ彼らはライブラリコードを使用し、通常はstd :: allocatorで十分です。