【问题标题】:Why can't scoped_ptr be used with STL containers?为什么 scoped_ptr 不能与 STL 容器一起使用?
【发布时间】:2014-05-24 11:27:11
【问题描述】:

boost 文档页面reads

scoped_ptr 不能在 C++ 标准库容器中使用。如果您需要一个智能指针,请使用 shared_ptr

我认为 不可复制 将成为scoped_ptr 的障碍,但由于 c++11,就某些容器而言,我们可以:

  • 使用emplace_back 等就地构建
  • 移动资源而不复制

那么 scoped_ptr 不能用于 STL 容器的原因是什么?

【问题讨论】:

  • 为什么不改用std::unique_ptr
  • 如果 C++11 是一个选项,请使用 std::unique_ptr,它在各方面都优于 scoped_ptr。后者只是作为一种廉价、可行的中途措施而存在,它在没有移动语义的情况下尽其所能(与破碎的std::auto_ptr 形成对比)。
  • @Jarod42 我想知道是否禁止使用(那是什么原因?)还是只是文档过期的情况。
  • @NikosAthanasiou:任何你有一个本地范围的scoped_ptr<T>,你都可以用unique_ptr<T> const替换它。任何你在标准容器中有scoped_ptr<T> 的地方,你都可以用unique_ptr<T> 替换它,你的生活会更快乐,整体上得到改善。
  • @Mankarse:至少你可以说如果你用std::unique_ptr 替换boost::scoped_ptr中断的代码是病态的。您可以根据移动性和切换代码路径做一些 SFINAE 条件,但是......为什么? :-)

标签: c++ c++11 boost stl containers


【解决方案1】:

文档有些过时。 Boost.ScopedPtr 是一个旧库,维护者并不关心使文档与 C++ 的最新发展保持同步。

理论上scoped_ptr-like 类可以工作(std::unique_ptr 证明了这一点);但实际上,boost::scoped_ptr 不能在许多标准容器中有用地使用,因为它有一个私有的复制构造函数并且没有移动构造函数。特别是,std::vectorstd::deque 要求它们的内容是可移动构造的。

scoped_ptr 可以在基于节点的容器中使用(因为这样的容器不要求它们的内容是可移动构造的),如果只使用容器接口的有限子集。如下代码有效:

std::list<boost::scoped_ptr<int>> list;
list.emplace_back(new int(16));

std::map<int, boost::scoped_ptr<int>> map;
map.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(10),
    std::forward_as_tuple(new int(14)));

即便如此,与仅使用 std::unique_ptr 相比,这还是不必要的痛苦(因为使用 std::unique_ptr 将允许您使用更大比例的标准容器接口)。

【讨论】:

  • 我会说文档有点过时,因为它建议使用auto_ptr 进行所有权转让...
  • @Jarod42:嗯......当然,文档有些过时(它甚至没有建议 scoped_ptr 被弃用以支持 const std::unique_ptr)。但它对于标准容器仍然有效(至少对于vectordeque)。
【解决方案2】:

由于状态是文档,

它提供了一个基本的“资源获取即初始化”工具,没有共享所有权或所有权转移语义。它的 名称 和语义的执行(通过不可复制)都表明它打算仅在当前范围内保留所有权。

问。为什么 scoped_ptr 没有 release() 成员?
A. 阅读源代码时,能够根据所使用的类型得出关于程序行为的结论是很有价值的。如果 scoped_ptr 有一个 release() 成员,则可以转移持有的指针的所有权,从而削弱其将资源生命周期限制在给定上下文中的作用。

scope_ptr 的存在是为了比已弃用的auto_ptr 更安全并代表 RAII。 现在在 C++11 中,我们有 std::unique_ptr 来表示唯一所有权。

【讨论】:

    猜你喜欢
    • 2012-12-02
    • 2021-12-15
    • 2021-05-08
    • 1970-01-01
    • 2023-03-29
    • 2018-03-09
    • 2021-06-14
    • 2012-10-09
    • 2020-03-18
    相关资源
    最近更新 更多