問題は見た目よりずっと難しい。アロケータの型はオブジェクトの型の一部であるため、アロケータのみが異なる型間での相互作用はほとんど許可されません。頭に浮かぶ最初の例は、std::string
定数参照を受け取る関数は、別のアロケーターを使用する文字列を受け取ることができないということです。そのような特定のケースの 1 つは、オブジェクトの構築中です。実際のところ、おそらくここでのケースの方が難しいでしょう。
たとえば、次のコードを考えてみましょう。
// Assume that you could construct from a different allocator
std::vector<int, allocator1> f() {
std::vector<int, allocator2> r;
// fill in
return r;
}
int main() {
std::vector<int, allocator3> x = f();
}
スタック内のローカル アリーナを使用し、共有メモリを使用する可能性allocator1
があるstd::allocator<int>
(つまり、既定のアロケータ) と考えてください。理論的には、コードは非常に単純です。ベクターが作成され、データが入力されます。return ステートメントでは、からコピーして新しい一時ファイルが作成され、最後にコピーして構築されます。allocator2
allocator3
r
r
x
その一時から。問題は、標準が可能な限りコピーを避けることを許可している (そしてコンパイラーが好む) ことです。上記の特定の例 (およびアロケーターを無視) では、コンパイラーは両方のコピーを省略し、バッファーを 1 回だけ作成します。これは高速で効率的です。ただし、アロケーターが異なる可能性があるため、NRVO やその他の種類のコピー省略を無効にする必要があります。(これらの最適化が有効になっている場合x
、 mainallocator2
は既に破棄されているローカル アリーナで を使用し、未定義の動作を引き起こします)。
あるアロケータを持つコンテナから別のアロケータへのコピー構築を有効にすると、混乱するか、現在の標準よりも深刻な混乱に陥る可能性があり、ステートフル アロケータであらゆる種類の興味深い問題を引き起こす可能性があります (たとえば、スレッドごとのアロケーターを使用し、データを共有キューに移動すると、別のスレッドでスレッドごとのアロケーターによって作成されたオブジェクトを保持するスレッドが 1 つになる可能性があります。ロック、明らかに安全なコードで競合状態を作成している可能性があります....
これは、C++ 委員会への古い提案です。より良い割り当てモデルに向けて、C++03 割り当てモデルに関するいくつかの懸念を提起し、ポリモーフィック アロケーター型 (それ自体の問題があります) を提案します。興味深い読み物になりますが、詳細に注意してください。すべてが見た目ほど優れているわけではありません。また、どちらのオプション (または C++03バージョン)