【问题标题】:Cohabitation of boost::shared_ptr and std::shared_ptrboost::shared_ptr 和 std::shared_ptr 的共存
【发布时间】:2012-09-01 03:39:00
【问题描述】:

我想在某个时候使用boost::log,但我无法将std::shared_ptr 作为参数传递,因为编译器(VS2010)无法将其转换为boost::shared_ptr

我真的不喜欢他们彼此是外星人这一事实。

是否有一种安全且透明的方法可以将一个转换为另一个,以免它们相互绊倒?

我不认为这是 this question 的重复声明两者相同。

【问题讨论】:

  • 对于 C++11 之前的答案,请参阅:stackoverflow.com/questions/6326757/…
  • 我对 std::array 与 boost::array 有类似的问题。
  • @alfC 我认为没有简单的方法可以在 std::arrayboost::array 之间进行转换而不复制数组的内容。
  • @alfC:即使编译器停止抱怨,这也是破坏智能指针状态的可靠方法。
  • 他们应该有相同的界面,为什么不破解 boost,并将boost/shared_ptr.hpp 的内容替换为#include <memory> namespace boost { using shared_ptr = std::shared_ptr 之类的内容?

标签: c++ boost c++11 shared-ptr


【解决方案1】:

你可以这样做:

template<typename T>
boost::shared_ptr<T> make_shared_ptr(std::shared_ptr<T>& ptr)
{
    return boost::shared_ptr<T>(ptr.get(), [ptr](T*) mutable {ptr.reset();});
}

template<typename T>
std::shared_ptr<T> make_shared_ptr(boost::shared_ptr<T>& ptr)
{
    return std::shared_ptr<T>(ptr.get(), [ptr](T*) mutable {ptr.reset();});
}

编辑:请注意,这不适用于对源 ptr 的弱引用。所以要小心那些!

【讨论】:

  • 构造函数的第二个参数到底是什么?它看起来(从构造函数签名)应该是一个删除器,但我不明白语法。
  • +1 哇,非常棒的技巧,使用按值捕获将原始ptr 的副本(以及额外的引用计数)保留在删除器 lambda 中。我花了一段时间才弄明白,我不得不承认。
  • @StephaneRolland lambda 删除器存储为boost::shared_ptr 的成员,它又拥有std::shared_ptr 的副本作为成员(由于按值 lambda 捕获),它递增原始对象的引用计数。所以每个boost::shared_ptr 通过它的deleter 成员增加原始对象的引用计数。但是当boost::shared_ptr(确实独立于std的)的引用计数达到0时,什么都不会被删除,因为deleter是一个空操作,但是deleter的销毁实际上会减少原始的refcount。
  • 如果有缺陷,该方法很有趣。删除器与计数保持在一起,并在所有 strong 引用超出范围时执行。这种方法的问题在于,在存在weak_ptr 的情况下,将调用删除器,并且不会发生任何事情,尽管至少存在weak_ptr,但对象的生命周期将被引用人为地延长在删除器内部,打破了weak_ptr/shared_ptrcombination 组合的语义。修复很简单,设计很好,只是实现需要改变:[ptr](T*){ptr.reset();}
  • @ronag 现在 lambda 不是必须是 mutable 吗? (是的,just confirmed。)
猜你喜欢
  • 2013-06-12
  • 2013-04-16
  • 1970-01-01
  • 2011-09-27
  • 2011-09-13
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
相关资源
最近更新 更多