2

私は現在、C++ での同時実行性について学んでおり、C++0x で可能になると信じているスレッドのベクトルを使用することに出会いました。ただし、現在のコンパイラにはムーブ対応コンテナーが実装されていないようで、 が削除されているためにエラーが生成std::thread::thread(const std::thread&)されます。つまり、ムーブ コンストラクター/ムーブ割り当てはstd::thread.

を使用してカスタムアロケーターを作成することで、この問題を回避できると考えているのは正しいですか

void MyAllocator::construct (pointer p, reference val)
/* should be non-const reference to val because using move constructor? */
{
    new ((void*)p) T (std::move(val));
}

それよりも

void allocator::construct (pointer p, const_reference val)
{
    new ((void*)p) T (val);
}

? または、このテーマの他のバリエーション (おそらく MyAllocator::construct のオーバーロードを使用)。

注意: これは主に、短期間の教育的な演習であり、コンテナ内のスレッドをいじるのに十分な作業を実行することを目的としています。MyAllocatorこのコンテキストでのみ使用します。ただし、これが実装されている可能性のあるライブラリを教えてください。ソースを突き詰めることができます。

4

3 に答える 3

2

この問題を回避する最も簡単な方法は、スレッドをヒープに割り当て、それらへのポインターを操作することです。

Boost Pointer Containerライブラリを確認してくださいboost::ptr_vector<std::thread>。あなたが探しているものは私には思えます。

于 2010-09-27T14:47:23.763 に答える
2

コンパイラが move-aware を提供しない場合は、カスタム アロケータを提供するだけでなくstd::vector、独自の特殊化を作成する必要があります。std::vector<std::thread>C++03vectorインターフェイス全体がコピーに依存していpush_back()ます。要素をコピーします。2 番目のパラメーターとして渡された要素のコピーresize()で空の要素を初期化します (それが の既定値であっても)。、、、およびは、ベクトルの再割り当てが必要な場合は要素をコピーし、その他の場合は要素を移動する必要があります。T()resize()reserve()insert()erase()push_back()

これは非常に一般的な問題であるため、(商用の) just::thread実装にそのような特殊化を含めましたstd::thread

于 2010-09-27T16:37:11.523 に答える
0

std コンテナーがコピー可能なオブジェクトのみを受け取るという要件は、アロケーターの実装よりも C++03 コンテナー インターフェイスに関係があります。例えば

vector<T> b(100);
vector<T> a;
a=b;
assert(a==b);

標準は、a==b が真であることを保証します。ただし、T がコピー可能でない場合、最良の場合でも a=b はコンパイルされません。最悪の場合、a=b は未定義です。さらに、

a.push_back(T());

に新しいスペースが割り当てられる可能性があり、フードの下には、古いストレージから新しい基本ストレージへのコピーが作成されます。

さらに、C++03 標準には、実装が実際に allocator.construct を呼び出さなければならないと述べているものは何もなく、実際、多く (gcc など) はそうしていません。

C++0x 標準は、移動可能な型のコンテナー インターフェイスに新しいメンバー関数を追加し、operator= などの要素が存在する場合の動作を明確にします。

www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf を参照してください。

于 2010-09-27T16:00:46.510 に答える