将标准::unique_ptr插入到提升:ptr_map

Insert std::unique_ptr into boost:ptr_map

本文关键字:ptr map 插入 标准 unique      更新时间:2023-10-16

我正在将一些旧代码移动到c ++ 14,它使用了已弃用的auto_ptr并且与boost:ptr_map配合得很好,你可以这样做:

auto_ptr<Foo> foo(new Foo);
boost:map_ptr<int, Foo> m;
m.insert(5, foo);

现在,将该auto_ptr替换为 unique_ptr,它不会编译:

unique_ptr<Foo> foo(new Foo);
boost:map_ptr<int, Foo> m;
m.insert(5, foo);            // Does not compile
m.insert(5, move(foo));      // Does not compile either,
// this should be the right thing to do
m.insert(5, move.release()); // Does compile, but isn't exception safe

map_ptr API 还不是最新的吗?

根据响应进行编辑,在我的情况下,使用 map of unique_ptr 不是一个好的选择,因为它需要重写相当数量的代码。我真的很想让它与map_ptr一起工作,我正在处理一些旧代码,我希望进行最少的更改。

我认为在 C++14 中你想要的是这个:

std::unordered_map<int, std::unique_ptr<Foo>> x;
x.emplace(5, std::make_unique<Foo>());

您不再需要那些旧的 boost _ptr容器,它们基本上是缺乏可以在容器中安全处理的拥有的零开销指针的解决方法(即unique_ptr)。

您可以使用

std::unordered_map<int, std::unique_ptr<Foo>> x;
x.emplace(5, std::make_unique<Foo>());

它是 C++14 的功能。不需要旧的升压容器!!:)

map_ptr API 还不是最新的吗?

不,你只是用错了方式使用它。

从文档中:

ptr_map是一个指针容器,它使用基础 std::map 来存储指针。

请注意,这不会编译:

unique_ptr<Foo> foo(new Foo);
void *ptr = foo;

由于您无法将std::unique_ptr转换为带有作业的void *,因此没有多大意义。
当你尝试这样做时,这或多或少是内部发生的事情:

m.insert(5, move(foo));

另一方面,这将编译:

unique_ptr<Foo> foo(new Foo);
Foo *bar = foo.realease();
void *ptr = bar;

这接近于:

m.insert(5, move.release());

因此,您不能期望第一种情况有效,实际上并非如此。


话虽如此,如今我宁愿使用标准模板库中的 int 和std::unique_ptr<Foo>映射并摆脱boost::ptr_map,正如问题评论中所建议的那样。
类似以下内容的内容应该有效:

std::map<int, std::unique_ptr<Foo>>

请注意,如果您想要更接近boost::ptr_map的工作方式,std::mapstd::unordered_map更合适,如上所述,其底层数据结构是std::map而不是std::unordered_map