1

我正在尝试将 a 替换为std::unordered_mapa 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 );

作为解决方法,您可以在独立向量中使用std::shared_ptr或存储s: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 回答