我正在尝试将std::unordered_map
替换为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编译为ex。)或者我错过了关于concurrent_hash_maps的内容?
答案 0 :(得分:3)
根据文档tbb::concurrent_hash_map
仅通过引发const&
副本的unique_ptr
获取参数:
bool insert( const value_type& value );
作为解决方法,您可以在独立媒介中使用std::shared_ptr
或存储unique_ptr
:
std::vector<std::unique_ptr<V>> ptrs;
并将原始指针存储在concurrent_hash_map
中。但是,这可能是您的用例(如频繁删除)所不能接受的。
另一种可能性是使用std::auto_ptr
或类似的东西。但这很危险 - 正确的副本应该进入存储桶,所以你必须测试它。
答案 1 :(得分: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
}
答案 2 :(得分: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));
}
};
虽然我对推荐它犹豫不决。