1

std::unordered_mapaを aに置き換えようとしていtbb::concurrent_hash_mapます。

私の元のコード:

typedef std::unique_ptr<V> V_ptr;

std::unordered_map<K, V_ptr> hm;
V_ptr v (new V);
K k;

hm.insert (std::make_pair (k, std::move (v)));

clang 3.3 で正常にコンパイルされます。unordered_map を concurrent_hash_map に切り替える:

typedef std::unique_ptr<V> V_ptr;

tbb::concurrent_hash_map<K, V_ptr> hm;
V_ptr v (new V);
K k;

hm.insert (std::make_pair (k, std::move (v)));

エラーが発生します:...stl_pair.h:105:21: error: call to deleted constructor of 'std::unique_ptr<...

これは clang 3.3 のバグですか? 多くのコンテナーで std::unique_ptrs を使用すると、gcc 4.5 で同様のエラーが発生したことを覚えています。(上記の元のコードは、例として gcc 4.5 ではコンパイルされません。) それとも、concurrent_hash_maps について何か見逃したのでしょうか?

4

3 に答える 3

3

ドキュメントによると、どのトリガーのコピーをtbb::concurrent_hash_map介してのみ引数を取ります:const&unique_ptr

bool insert( const value_type& value );

回避策として、スタンドアロンのベクターで s を使用std::shared_ptrまたは保存できます。unique_ptr

std::vector<std::unique_ptr<V>> ptrs;

生ポインタを に保存しconcurrent_hash_mapます。ただし、それはユースケース (頻繁な削除など) には受け入れられない場合があります。

別の可能性は、std::auto_ptrまたは同様のものを使用することです。しかし、それは危険です。正しいコピーがバケットに届くはずなので、テストする必要があります。

于 2013-10-30T20:14:14.363 に答える
0

おそらく、tbb::concurrent_hash_map へのより複雑な形式の挿入を使用することで、この制限を回避できます。次のコード スニペットはテストされていませんが、機能しない理由はアプリオリにはわかりません。

typedef std::unique_ptr<V> V_ptr;

tbb::concurrent_hash_map<K, V_ptr> hm;
V_ptr v (new V);
K k;
{ // this scope controls lifetime of the accessor
    tbb::concurrent_hash_map::accessor a;
    hm.insert (a, k);          // insert or find the key
    a->second = std::move(v);  // assign the value
}
于 2013-11-01T20:46:22.553 に答える
0

私の質問に対する答えは、tbb はまだ std::move をサポートしていないということであることに同意します。今のところ shared_ptr を使い続けるつもりですが、次の回避策はうまくいきます:

struct V_ptr : public std::unique_ptr<V> {

    typedef std::unique_ptr<V> uvptr;
    using uvptr::uvptr;
    V_ptr () : std::unique_ptr<V> () {};

    V_ptr (const V_ptr& rhs) {
        this->swap (const_cast<V_ptr&> (rhs));
    }
};

私はそれをお勧めすることをためらっていますが。

于 2013-11-04T22:02:34.260 に答える