在地图中构建一个不可移动的对象

时间:2015-10-29 19:28:52

标签: c++ c++11 move-semantics stdatomic

我试图在包含原子的地图中构建一个对象,因此既不能复制也不能移动AFAICT。

我对C ++ reference的解读是地图emplace应该能够做到这一点。但是由于已删除或不存在的构造函数,以下代码无法编译。使用make_pair无济于事。

#include <atomic>
#include <unordered_map>

class Z {
  std::atomic<int> i;
};

std::unordered_map<int, Z> map;

void test(void) {
  map.emplace(0, Z()); // error
  map[0] = Z(); // error
}

这可能,如果没有,为什么不呢?

编辑:编译器是gcc 4.8.1,在Linux上

3 个答案:

答案 0 :(得分:13)

map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple())将在Z位置构建零参数0

map[0]如果还没有,也会这样做。

emplace接受构造std::pair<const K, V>的参数。 std::pair有一个std::piecewise_construct_t标记的构造函数,它带有两个元组,第一个用于构造第一个参数,第二个用于构造第二个参数。

因此std::pair<const int, Z> test( std::piecewise_construct, std::make_tuple(0), std::make_tuple() )就地构建了test个元素,const int(0)构成。 Z()构建。

map.emplace转发是std::pair构造函数的参数。

答案 1 :(得分:2)

最简单的解决方案是使用operator[]在地图中构造值。然后您可以指定一个值(或根据需要对其进行操作)。

答案 2 :(得分:-1)

可能以下解决方案会更好,因为原子不可复制:

class Z {
  std::atomic<int> i;
};

std::unordered_map<int, std::shared_ptr<Z>> map;

void test(void) {
  map.emplace(0, std::make_shared<Z>()); // OK
}