compilation error when using std::unique_ptr as value in tbb::concurrent_hash_map

独自空忆成欢 提交于 2019-12-11 11:22:03

问题


I'm trying to replace a std::unordered_map with a tbb::concurrent_hash_map.

My original code:

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)));

compiles fine with clang 3.3. Switching the unordered_map to a 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)));

results in the error: ...stl_pair.h:105:21: error: call to deleted constructor of 'std::unique_ptr<...

Is this a bug in clang 3.3? I remember there being similar errors in gcc 4.5 when using std::unique_ptrs in many containers. (The above original code will not compile with gcc 4.5 for ex.) Or maybe I missed something about concurrent_hash_maps?


回答1:


According to documentation tbb::concurrent_hash_map takes argument only via const& which triggers copy of unique_ptr:

bool insert( const value_type& value );

As workaround you may use std::shared_ptr or store unique_ptrs in stand-alone vector:

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

and store raw pointers in concurrent_hash_map. Though, that may be not acceptable for your use cases (like frequent deletions).

Another possibility is to use std::auto_ptr or something similar. But that is dangerous - right copy should arrive into bucket, so you have to test it.




回答2:


Probably you can work around this limitation by using a more complex form of insertion into tbb::concurrent_hash_map. The following code snippet is not tested, but a priori I see no reason why it would not work:

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
}



回答3:


I agree that the answer to my question is that tbb does not support std::move yet. I'm going to stick with shared_ptr for now but the following work around does work:

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));
    }
};

Though I'm hesitant to recommend it.



来源:https://stackoverflow.com/questions/19692763/compilation-error-when-using-stdunique-ptr-as-value-in-tbbconcurrent-hash-ma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!