问题
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_ptr
s 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