用 unique_ptr 的 value_type 构建 unordered_map

Construct unordered_map with a value_type of unique_ptr

这段代码似乎不起作用,因为唯一指针被存储到一对对象中,然后试图从中复制。这可以避免吗?

std::unordered_map<std::string,std::unique_ptr<int>> _map {
    {"hello", std::make_unique<int>(7)}
};

可以在此处查看完整的代码示例和编译错误 http://cpp.sh/7uc3a

是的,不使用列表初始化。

std::unordered_map<std::string,std::unique_ptr<int>> _map;
_map.insert({"hello", std::make_unique<int>(7)});

std::unordered_map 需要调用复制或移动构造函数才能将任何键和值存储在其内部缓冲区中。在 std::unique_ptr 的情况下,复制构造函数被删除,因为制作 std::unique_ptr 的副本会使它变得不唯一。这只剩下移动构造函数。 问题在于您如何初始化地图:

std::unordered_map<std::string,std::unique_ptr<int>> _map {
    {"hello", std::make_unique<int>(7)}
};

您正在使用 std::initializer_list.

初始化地图的值

来自 cppreference:

An object of type std::initializer_list is a lightweight proxy object that provides access to an array of objects of type const T.

实际上,初始化列表中的所有值都是常量。这意味着无法调用 std::unique_ptr 上的移动构造函数,因为移动对象通常需要修改原始实例。由于 std::unique_ptr 无法移动,编译器转而使用复制构造函数,这就是它最终抱怨复制构造函数被删除的原因。

我发布的代码片段有效,因为 insert 接受非常量 std::pair,这意味着 std::unique_ptr 是非常量,并且可以调用其移动构造函数。